Complete Python Course with 10 Real-World Projects (NEW) | Ardit Sulce | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Complete Python Course with 10 Real-World Projects (NEW)

teacher avatar Ardit Sulce, Python Instructor, Founder of PythonHow

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Intro Video

      1:53

    • 2.

      Introducing the First Steps

      1:39

    • 3.

      Installing Python and the IDE

      0:57

    • 4.

      Installation Instructions on Windows +

      5:56

    • 5.

      Installation Instructions on Mac +

      5:12

    • 6.

      Installation Instructions on Linux +

      2:11

    • 7.

      Creating & Running a Python Program

      9:29

    • 8.

      What is Python Surprisingly?

      3:35

    • 9.

      Starting with the Basics of Python

      1:39

    • 10.

      Variables: Why and How to Use Variables +

      6:05

    • 11.

      Using The Python Interactive Shell

      7:03

    • 12.

      Using the Terminal

      4:17

    • 13.

      Simple Types: Integers, Strings, and Floats

      3:21

    • 14.

      List Data Types

      1:31

    • 15.

      Using Ranges

      5:18

    • 16.

      What are the Attributes of Data Types

      2:54

    • 17.

      How to Find Out What Code You Need

      3:33

    • 18.

      Dictionary Data Types

      3:43

    • 19.

      What Makes a Programmer a Programmer

      2:10

    • 20.

      Tuple Data Types

      2:26

    • 21.

      Using Data Types in the Real-world +

      1:07

    • 22.

      Operations with Data Types

      0:55

    • 23.

      Error Messages in Python 3.10

      4:00

    • 24.

      Making More Operations with Lists

      5:56

    • 25.

      How to Access List Items

      2:04

    • 26.

      How to Access List Slices

      2:49

    • 27.

      How to Use Negative Indexes

      2:02

    • 28.

      How to Access Characters & Slices in Strings

      1:30

    • 29.

      How to Access Items in Dictionaries +

      1:52

    • 30.

      More Python Basics: Functions and Conditionals

      1:39

    • 31.

      How to Create Your Own Functions +

      5:25

    • 32.

      When to Use Print and Return +

      3:59

    • 33.

      Introduction to Conditionals

      0:58

    • 34.

      Using the If Conditional

      3:48

    • 35.

      A Conditional Explained Line by Line

      3:09

    • 36.

      More Information on Conditionals +

      2:21

    • 37.

      Using the Elif Conditional

      1:15

    • 38.

      White Space +

      3:30

    • 39.

      More Python Basics: Processing User Input

      0:38

    • 40.

      Learning More on User Input

      7:55

    • 41.

      String Formatting +

      4:51

    • 42.

      String Formatting with Multiple Variables +

      4:17

    • 43.

      Introduction to For Loops +

      0:59

    • 44.

      How and Why to Use For Loops

      5:46

    • 45.

      How to loop Through a Dictionary +

      1:12

    • 46.

      How and Why to Use While Loops

      2:59

    • 47.

      While Loops with User Input

      3:12

    • 48.

      While Loops, Break and Continue +

      3:22

    • 49.

      Building a Program in Python

      0:59

    • 50.

      Problem Statement in Python

      3:48

    • 51.

      Approaching the Problem

      1:46

    • 52.

      Building the Maker Function

      5:14

    • 53.

      Constructing the Loop

      4:39

    • 54.

      Making the Output User-Friendly

      3:28

    • 55.

      Introduction to List Comprehension

      0:50

    • 56.

      A Simple List Comprehension

      3:27

    • 57.

      List Comprehension with an If Conditional

      1:22

    • 58.

      List Comprehension with a If-Else Conditional +

      1:37

    • 59.

      More About Functions

      0:35

    • 60.

      Functions with Multiple Arguments

      1:45

    • 61.

      Default & Non-default Parameters, Keyword & Non-keyword Arguments

      3:00

    • 62.

      Functions with a Arbitrary Number of Non-keyword Arguments

      3:32

    • 63.

      Functions with a Arbitrary Number of Keyword Arguments +

      1:34

    • 64.

      Introduction to File Processing

      1:30

    • 65.

      Processing Files With Python

      1:12

    • 66.

      Reading Text from a File +

      3:07

    • 67.

      File Cursor

      1:49

    • 68.

      Closing a File

      1:34

    • 69.

      Opening Files using with

      1:45

    • 70.

      Using Different Filepaths

      1:25

    • 71.

      Writing Text in a File

      3:59

    • 72.

      Appending Tex to an Existing File +

      3:30

    • 73.

      Builtin Modules in Python

      5:53

    • 74.

      Standard Python Modules

      8:34

    • 75.

      Third-Party Modules

      6:28

    • 76.

      An Example onThird-Party Modules

      2:45

    • 77.

      Intro to Using Python with CSV, JSON, and Excel Files

      0:35

    • 78.

      The Pandas Library for + Data Analysis

      3:07

    • 79.

      Getting Started with Pandas

      8:37

    • 80.

      Setting Up the Jupyter Notebook +

      9:05

    • 81.

      Loading Csv Files in Python

      4:20

    • 82.

      Loading Excel Files in Python

      0:58

    • 83.

      Loading Text Files in Python

      2:30

    • 84.

      Introduction to Numpy ++

      8:07

    • 85.

      How to Convert Images to Numpy Arrays

      5:40

    • 86.

      Indexing, Slicing, and Iterating Numpy Arrays

      4:07

    • 87.

      Stacking and Splitting Numpy Arrays

      5:44

    • 88.

      App 1: Web Map with Python and HTML +

      1:05

    • 89.

      HTML & Python: Creating an HTML Map with Python +

      11:35

    • 90.

      HTML&Python Adding a Marker to the Map

      8:23

    • 91.

      HTML & Python: Using For-loops when Adding Multiple Markers

      4:43

    • 92.

      HTML & Python: File Processing by Adding Markers from Files

      13:06

    • 93.

      HTML&Python: String Manipulation

      5:07

    • 94.

      Using Functions - Creating a Color Generation Function for Markers ++

      7:55

    • 95.

      HTML & Python: How to Add and Stylize Markers

      1:53

    • 96.

      HTML & Python: Working with JSON Data

      5:34

    • 97.

      Python & JSON: Adding a Population Map Layer

      3:20

    • 98.

      Python & JSON: Stylising the Population Layer

      9:34

    • 99.

      Python & JSON: Adding a Layer Control Panel +

      6:23

    • 100.

      App 2: English Thesaurus +

      4:10

    • 101.

      Understanding Your Dataset in Python +

      4:54

    • 102.

      Loading JSON data in Python

      3:52

    • 103.

      Making the App Return the Definition of a Word

      3:25

    • 104.

      How the App Deals with Non-existing Words

      2:51

    • 105.

      How the App Deals with Case-Sensitive Words

      3:09

    • 106.

      Calculating the Similarity Between Words

      4:39

    • 107.

      Finding the Best Matches out of a List of Words

      6:07

    • 108.

      Finding the Most Similar Word from a Group of Words

      9:42

    • 109.

      Getting Confirmation from the User

      10:17

    • 110.

      Optimising the Final Output +

      7:51

    • 111.

      How to fix Syntax Errors in Python

      8:22

    • 112.

      How to Fix Runtime Errors in Python

      10:58

    • 113.

      How to Fix Difficult Errors

      5:38

    • 114.

      How to Ask a Good Programming Question

      5:59

    • 115.

      Making the Code Handle Errors by Itself

      7:59

    • 116.

      Introduction to Computer Vision with Python +

      2:29

    • 117.

      Loading, Displaying, Resizing, and Creating Image ++s with OpenCV

      14:00

    • 118.

      Explanation of Previous Exercise

      4:29

    • 119.

      Detecting Faces in Images with OpenCv and Python

      19:38

    • 120.

      Capturing Video with OpenCv and Python

      19:45

    • 121.

      App 3: Webcam Motion Detector App

      1:58

    • 122.

      Detecting Moving Objects from the Webcamp with Python

      29:57

    • 123.

      Storing Object Detection Timestamps in a CSV File ++

      20:38

    • 124.

      Introduction to the Bokeh Library +

      2:02

    • 125.

      Creating Your First Bokeh Plot

      13:52

    • 126.

      Using Bokeh with Pandas +

      4:51

    • 127.

      Creating a Time-Series Plot +

      6:36

    • 128.

      More Visualisation Examples with Bokeh

      4:21

    • 129.

      Plotting Time Intervals from the Data Generated by Webcam App

      14:05

    • 130.

      Implementing a Hover Feature

      9:57

    • 131.

      App 4 Part 1 - Data Analysis and Visualizations with Pandas and Matplotlib +++

      2:52

    • 132.

      Exploring the Dataset with Python and Pandas +

      9:17

    • 133.

      Selecting Data with Python

      13:32

    • 134.

      Filtering the Dataset

      7:58

    • 135.

      Time-Based Filtering

      9:55

    • 136.

      Turning Data Into Information

      11:00

    • 137.

      Aggregating and Plotting Average Ratings by Day

      14:43

    • 138.

      Downsampling and Plotting Average Ratings by Week

      9:42

    • 139.

      Downsampling and Plotting Average Ratings by Month

      2:16

    • 140.

      Average Ratings by Course by Month

      10:44

    • 141.

      What Day of the Week are People the Happiest

      9:45

    • 142.

      Other Types of Plots +

      6:06

    • 143.

      App 4 (Part 2): Data Analysis and Visualization with In-Browser Interactive Plots

      2:55

    • 144.

      Making a Simple Web App

      12:24

    • 145.

      Making a Data Visualisation Web App

      23:26

    • 146.

      Changing Graph Labels in the web App

      2:59

    • 147.

      Adding a Time-Series Graph to the Web App

      5:20

    • 148.

      Multiple Time-Series Plots

      18:59

    • 149.

      Creating Multiple Time-Series Streamgraphs

      6:55

    • 150.

      Adding a Pie Chart to the Web App +

      9:29

    • 151.

      Demo of App 5: Web Development with Flask: Building a Personal Website

      1:41

    • 152.

      Your First Flask Website with Server Warning Added

      8:07

    • 153.

      Preparing HTML Templates +

      4:09

    • 154.

      Adding a Website Navigation Menu

      8:32

    • 155.

      Improving the Website Frontend with CSS ++

      5:59

    • 156.

      Creating a Python Virtual Environment

      6:22

    • 157.

      How to Use the PythonAnywhere Service

      7:47

    • 158.

      Deploying the Flask App on PythonAnywhere +

      7:52

    • 159.

      Introduction to the Tkinter Library

      2:35

    • 160.

      Creating a GUI Window and Adding Widgets

      9:11

    • 161.

      Connecting GUI Widgets with Functions ++

      9:32

    • 162.

      How Python Interacts with Databases

      3:00

    • 163.

      Connecting to an SQLite Database with Python

      13:11

    • 164.

      SQLite: Selecting, Inserting, Deleting, and Updating SQL Records

      6:53

    • 165.

      PostgreSQL Database with Python

      8:46

    • 166.

      PostGreSQL: Selecting, Inserting, Deleting, and Updating SQL Records

      12:51

    • 167.

      App 6: Book Inventory App

      2:25

    • 168.

      Designing the User Interface

      5:54

    • 169.

      Coding the Frontend Interface

      13:28

    • 170.

      Coding the Backend of the App

      24:28

    • 171.

      Connecting the Frontend with the Backend, Part 1

      17:30

    • 172.

      Connecting the Frontend with the Backend, Part 2 ++

      21:59

    • 173.

      Creating .exe and .app Executables from the Python Script

      5:00

    • 174.

      What is Object Oriented Programming (OOP)

      4:59

    • 175.

      Using OOP in a Program, Part 1

      13:01

    • 176.

      Using OOP in a Program

      14:05

    • 177.

      Creating a User Login Page

      21:55

    • 178.

      Creating a Bank Account Class

      21:10

    • 179.

      Creating Classes Through Inheritance

      12:08

    • 180.

      OOP Glossary +++

      8:12

    • 181.

      App 7: Mobile Feel-Good App Demo +

      1:27

    • 182.

      Creating a User Sign Up Page

      9:52

    • 183.

      Capturing User Input

      6:25

    • 184.

      Processing User Sign Ups +

      11:22

    • 185.

      Creating a Sign Up Success Page

      4:27

    • 186.

      Switching Between Pages

      2:55

    • 187.

      Processing User Login Credentials

      16:52

    • 188.

      Displaying Output to the User +

      15:10

    • 189.

      Stylizing the Login Page

      14:22

    • 190.

      Stylizing the Sign Up Page

      1:11

    • 191.

      Making the Buttons Interactive

      9:01

    • 192.

      Creating a Scrollable Area

      8:22

    • 193.

      Preparing the Environment to Deploy the Mobile App

      13:10

    • 194.

      Creating an APK file for Android

      10:29

    • 195.

      Installing the APK file on Android

      3:52

    • 196.

      Web Scraping with Python & Beautiful Soup

      1:57

    • 197.

      How Web Scraping Works +

      4:30

    • 198.

      Web Scraping Example with Python

      16:22

    • 199.

      App 8: Web Scrapping App Demo ++

      2:28

    • 200.

      Loading the Webpage in Python

      7:15

    • 201.

      Extracting Div Elements

      11:34

    • 202.

      Scraping the Addresses of the Properties

      14:39

    • 203.

      Scraping Special Elements

      12:06

    • 204.

      Saving the Extracted Data in CSV Files

      8:26

    • 205.

      Crawling Through Multiple Web Pages +

      17:15

    • 206.

      App 9: Django & Bootstrap Blog and Translator App +

      10:56

    • 207.

      Setting Up a Virtual Environment

      12:42

    • 208.

      Creating Django Project

      11:12

    • 209.

      Creating Database Model for the Blog App

      12:22

    • 210.

      Views in Djago

      4:41

    • 211.

      URL Patterns

      15:16

    • 212.

      Creating Admin Interface Views

      8:51

    • 213.

      Creating the Homepage

      7:32

    • 214.

      Creating the About Page

      2:44

    • 215.

      Listing Blog Posts on the Homepage

      8:04

    • 216.

      Adding Bootstrap to Django

      16:28

    • 217.

      Template inheritance

      12:37

    • 218.

      Applying Bootstrap Styling to the Navigation Menu

      4:14

    • 219.

      Demo of the Django Translation App

      3:11

    • 220.

      The Step of the Django App Development

      3:29

    • 221.

      Creating an Empty App Structure for the Translator App

      2:39

    • 222.

      Creating a Django Form

      7:45

    • 223.

      Getting and Processing User Input Through a Form

      10:09

    • 224.

      Completing the Translator App

      6:12

    • 225.

      Demo of App 10: Geocoder Web App +

      7:31

    • 226.

      Part 1 of Building the Geocoder Web App

      16:21

    • 227.

      Part 2 of Building the Geocoder Web App +

      5:51

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

7

Students

--

Projects

About This Class

About This Class

If you've always wanted to learn Python but have no prior programming experience, this class is for you!

Ardit has spent years teaching Python to beginners and has developed a hands-on, project-based approach that makes learning both fun and practical. You'll gain essential programming skills while working on real-world applications, helping you build confidence and independence in coding.

In this class you'll learn:

  • Python fundamentals, including syntax, variables, loops, and functions

  • How to build 10 real-world applications from start to finish

  • Web development with Flask and Django

  • Data analysis and visualization techniques

  • Desktop GUI application development

  • Web scraping techniques to extract data from websites

  • Deploying applications to live servers and creating standalone executables

  • Best practices for writing clean, efficient, and maintainable code

You’ll be creating: A portfolio of 10 practical applications, including:

  1. A volcano web map generator

  2. An object detector using live webcam feeds

  3. A personal website with Python and Flask

  4. A book inventory desktop app with an SQL database backend

  5. A data analysis and visualization dashboard

  6. A mobile app compatible with Android and iOS

  7. A real estate web scraper

  8. A form-based web app that collects and emails user data

  9. A blog and translator web app built with Django

  10. An Excel file processor for data management

Even if you're completely new to coding, you'll find these step-by-step techniques easy to follow and apply to your own projects!

How to find the resources connected to the lessons? 

If you see that the name of a lecture followed by a "+" sign, please check the attached files available on this link for a resource with the same number as the lesson with the "+" sign. There you will also find the source code of the 10 applications built in the course.

You can also find Ardit here:
Website: https://pythonhow.com/

Meet Your Teacher

Teacher Profile Image

Ardit Sulce

Python Instructor, Founder of PythonHow

Teacher

Hi, I am Ardit! I am a Python programmer, and a top Python instructor on Udemy having taught over 500,000 students through my courses. I have used Python together with companies from various countries, such as the Center for Conservation Geography, to map and understand Australian ecosystems, image processing with the Swiss in-Terra, and performing data mining to gain business insights with the Australian Rapid Intelligence.

Teaching is my passion and you will find that I love to explain everything using real-world examples.

Happy learning!

See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Intro Video: Hi, I'm Ardit a Python developer and instructor with years of experience teaching programming to over 500,000 students worldwide. I'm also the founder and author at pythonhow.com, a hub about Python. I've created some of the most popular Python courses online, and in this Skillshare class, I'll guide you from beginner to advanced Python skills by building real world projects. Course starts with the fundamentals, so no prior experience is needed. We'll cover Python from scratch and as we progress, we'll apply what we learned by building ten real world applications. You'll gain hands on experience with data analysis using Pandas, working with essential datasets with Python such as JSO, SQL, CSV, even developing web applications and desktop applications. You will even create a mobile app using the Kev library in Python. These are real world applications with real data and a lot of features, you'll gain real hand on experience, ready to apply these skills for a job as a programmer afterwards. So who is the course for? The class is perfect for beginners who want to learn Python from ground up, as well as intermediate learners looking to build practical projects. So no preer coding experience is required, just a computer and willingness to learn. The best way to learn programming is by doing, so that's exactly what we focus on in this class. Each project you build will reinforce your skills and give you something tangible to showcase. So if you're ready to learn Python in an engaging and practical way, let's get started. I'll see you in the first lesson. 2. Introducing the First Steps: Hi, welcome to a new video, and this is an introductory video of the functions and conditionals section. So now you're entering a more advanced section of Python. Functions and conditionals are some advanced core concepts of Python, and these are very fundamental blocks which you can use to make your programs more intelligent and more manageable. So you make your programs more intelligent by making them take decisions and that you can implement via conditionals. So if your program gets some inputs and you want to think, you want to make your program think if that input is fine or not, and you want to do something if that input is true and something else if that input is false. So you're making decisions in your program through a conditional block. And then you have functions on the other hand, functions are used to wrap in blocks of code, so similar blocks of code. It helps you organize your code. So a function, for example, could convert USD to euros. So this function does this certain things and does it well. So it gets USD as input, and it gives you euros as output. So inside the function, you have those math operations which do the conversion. So conditions and functions are two things you're going to learn this section through examples, of course. So I'll see you in the next video. 3. Installing Python and the IDE: Hi. In this lecture, I'll show you how to install Python and the Visual Studio code IDE. Now, if you have Python installed and if you have already an IDE, you can skip this video. So you can also use other IDEs. Visual Studio code is just my preference, and I do recommend using Visual Studio code. So where are the instructions? Well, if you prefer text based instructions, you can download the PDFs from the lecture resources. If you want video instructions, videos are longer. So if you have trouble with a text version, maybe, maybe you want to download the videos afterwards. But the text versions should be enough. And instructions are for Windows, Mac and Linux users. So depending on your operating system, you might want to select to download the files that are for your own operating system. So thank you, and I'll talk to you in the next lecture. 4. Installation Instructions on Windows +: Hi, in this part, I'll show you how to install Python on Windows and also visual tudo code on Windows as well. So let's start by installing Python. Just search on Google for Python, and the first page should be the official Python website, python.org. On python.org, go over to Downloads and go to this button. So currently, the current version is Python 3.10 0.3. In your case, it could be Python 3.11 perhaps. So whatever you see there, just download it. One thing if you are on Windows seven or earlier, then you should go to this link viewful list of downloads and download Python 3.8 or earlier because 3.10 will not work for Windows seven or older version of Windows. So now I'll click on Python 3.10 0.3. This executable file will download, then you should install that executable this window should show up. Now, if you have a Python installation already, this button here will say upgrade instead of install. So if that's the case, just upgrade. If you don't have any Python on your system, then you should press on Install Now, but you should also check this at Python 3.10 to path. So make sure that is checked and go to Install Now or upgrade. My setup was successful, so I'll close this window and go to the Windows search button and open Command Prompt. So search for Command Prompt or simply CMD and open this app. Now, this is a command line interface that allows you to interact with your Windows operating system. So now let's make sure that Python was installed successfully. For that, you want to type P Y, space minus three. Press Enter, and if this shows up with these three arrows, that means Python was installed. So what you're looking at now is the Python interactive shell, also known as the Python console. So here now, you can type in Python code. For example, 3.4, press Enter and you get the results seven. This is known as an interactive way of programming. To exit this, you can press exit with parenthesis, open and close the parenthesis, press Enter, and you go back to the Windows command line. Now, if we close this window, we will lose that code that we wrote there, so we didn't save the code. That was simply an interactive session where you just type in some codes for testing purposes and you don't want to save the code. If you want to save the code, then you need an IDE. So that's what we're going to do next. We're going to install an IDE. So go over to Google search for Visual Studio code. But if you want to use another IDE, for example, Pycharm, feel free to use it. The Python code that I will write on Visual Studio code will be the same that you will write on your own. Favorite IDE. The IDE is just a matter of preference. So let's go ahead and click the first results. Visual Studio code. Don't confuse Visual Studio code with Visual Studio. These are two different IDEs. Visual Studio code, download for Windows and wait for the executable file to download. Then you want to click the executable to install it. So just go over the installation process. Next, next. Next, I prefer to check these options. It gives you the option to open Python files on Visual Studio code by right clicking over your Python files on your Windows Exploder. Then click on Next and Install. My installation was successful, so I'll finish this, and now I'll open Visual Studio code. So I'll just search for Visual Studio code, or if you do just VSC, that's the acronym used for Visual Studio code, usually. So you should open Visual Studio code. You have some release notes there. If you want to read them, I'll close that close this window as well. And so that is Visual Studio code. The setup of Python and Visual Studio code was successful on my computer. Both Python and Visual psudio code are working well. Now, in the next video, I'll show you how to use the two together, so how to use Python inside Visual Studio code. I'll tell you in the next video. 5. Installation Instructions on Mac +: Hi. In this video, I'll show you how to install Python and the Visual Studio code IDE on Mac. We're going to start by installing Python. So if you search for Python on Google, the first results should point you to the official Python web page. And if you go over to download and then go over to this button, this should download the latest version of Python. In my case, this is 3.10 0.3. In your case, it could be even newer, for example, 3.11. Whatever the version here is, just press the button and it will download the installation package. Then click over the file to install it. Now, if you have another version of Python installed on your computer, you can still install this newer version. The two versions will behave as separate independent software, and you can use them both. I'll show you how to do that. So press continue, continue, continue. Agree. Install. My installation of Python was successful. So now to check if Python was really, really installed successfully, I can open the terminal. So for that, you want to use spotlight to search for terminal or Alfred. If you use Alfred, so open the terminal program, and on the terminal, you want to type in Python 3.10 or 0.11 if you installed Python 3.11. So depending on what you had here, you want to type in that version. Just like that without spaces. So 3.10 in my case, press Enter and this should show up. So you see these three arrows here. Here you can write codes, for example, three plus four, and you get the output seven. So that's known as Python interactive shell or the Python console. It's a quick way to write code. You can exit the shell, the Python shell to go back to the terminal. So there we go. And now we are in the terminal. If you want to use another version of Python that you had installed, you can use Python 3.9, for example, if you had Python 3.9 installed, and that should open that other version of Python as you see here. Again, you can exit, go back to the terminal. You can close that window, and now the code is also lost. So we didn't save the code in any file. We can do that by using an IDE, and that's what we're going to do next. We're going to download and install Visual Studio code. Visual Studio code is an IDE. Now, the IDE is a matter of preference. So if you have a favorite ID, for example, you were using Pycharm before, feel free to use Pycharm because the code that I write in the videos will be the same. In my case, I'll be using Visual Studio code. So just search on Google for that, go to the first results, and this should take you to Visual Studio code. Now, don't confuse Visual Studio code with Visual Studio. These are two different IDEs. Visual Studio code is the one we're using. So press that button to download Visual Studio code and wait for the installation to download. So that's downloaded a Zip file for me. The zip file was extracted, and now I have this file if I double click it and press on open. That will open Visual Studio code. So that's Visual Studio code. Note that the application is currently in my downloads folder. So you might want to drag that file to the applications folder. You can close that Visual Studio code window, and normally you can open that using Spotlight or if you're using Alfred then you can search for Visual Studio Code, and you see it in my applications folder now visualsudio code dot app. Open it and that's again, Visual Studio Code. In the next video, I'll show you how to use Python inside Visual Studio code so that we can create programs in files which we can save and reuse. So I'll talk to you in the next video. 6. Installation Instructions on Linux +: Here is how to install Python and the Visual Studio code IDE on Linux computers. You can install Python on Linux using the terminal. So search for terminal among your programs, open terminal, and first, you want to do a psudo app update. Enter the password for your Linux for sudo and press enter. Once the update finishes, then you want to do sudo app install Python three. And that should install Python on your computer. And the latest version of Python available was installed. That's why I got this message here that says Python three is already the news version, so everything is fine. Let's now install Visual Studio code IDE. So open your browser, go to the official website of Visual Studio Code, which is code.visualstudio.com. Otherwise, search on Google for Visual Studio Code. But don't confuse Visual Studio code with Visual Studio. Visual Studio and Visual Studio code are two different IDEs, and the one we're using in the course is Visual Studio code. So then in the website, go to the deep file download. And wait until the file is downloaded, and then double click the file. Visual Studio code is also available to be installed as a Snap package, so that would be an alternative of installing it. Otherwise, you can follow my instructions. Enter your Linux passwords and wait for the installation to complete. Once the installation is completed, you can go and search for Visual Studio code, so s should show up Visual Studio, which you can open and it should look like this. That was how to install Python and Visual Studio code on Linux. In the next video, I'll show you how to create your first Python program in Visual Studio code. Thanks. 7. Creating & Running a Python Program: Hi, welcome back. In this video. I'll show you how to build a Python program and how to execute that Python program so that you can get the output. Obviously, this program will be very simple because the focus here is to show you the process of creating a program and executing it. To build a program in Python, you need two things. One is Python and the other is an IDE or a text editor. An IDE is just an advanced text editor. So I'll use visual cilia code as the IDE. Which is this one in here, and then I will create a project here. A project is nothing more than just creating an empty directory. So first, you want to go to your file system, Windows Explorer or MacFinder and make sure you have an empty folder. First project is the name of this empty directory. On Windows Explorer, and then you want to go back to Visual Studio code. If you are on another IDE, the process is basically the same. You go to file, and then you go to OpenFolderO Make it could be written just open. So click on that. And then you want to browse to that empty folder, double click it, and then select folder. A Visual Studio code, what it will do is it will open that folder as the root directory of the project. You have this warning here, it's fine to say, yes, I trust the authors. You can see now that first project, the name of a folder is the name of the project as well. So what I'll do now is write a program, a Python program. And this consists of creating a text file where you write that actual program. To create that text file, you can go to your folder again and create it here, or normally what we do is we create that file from within the IDE. So if you click here, then write a name for the file such as M underscore program. It's not recommended to use spaces in the names of the files. So please always use underscores instead of space. And then, let's try TXT and see if this will work. The actual extension is dot PY, but that is not a requirement. Of course, we will use dot PY, always, always. But for now, let's keep it at dot TXT so that you understand a very crucial concept about Python. So I'll press Enter, and here I will do print three plus four, and that's our program. So this program simply outputs the sum of three and four. How can I execute this program now to get the results? Well, you see this terminal menu item here, you press that and go to new terminal, and that should open a new terminal in here. So that's like the command line where you interact with your computer. And here now, we can write Py minus three if you are on Windows. If you are on Mac, you should write Python three. So I'm on Windows here, so I'll use Pi space minus three, and then my underscore program, actually, I can use the tab now. If I press the tab, that will auto complete the file name. This part here is not necessary the dots and the backslash. You can leave it. It's fine. But even if you remove it like that, it will still work. So now, if you press Enter here, what we get is we go to the next line. Perhaps you were waiting for the output to show in here. It didn't show up because the file is still empty. We haven't saved the changes. So after I wrote this line of code, I didn't save anything. So what you want to do is you want to go to File Save or controls then press the upper arrow key in here to get that previously executed command and press Enter. Then we get the output seven. So as you can see, a Python program is nothing more than just a text file that you write and then you execute it using the Python command. But there is a nicer way to execute Python programs at least on Visual Studio code. And that is by using a Run button. Currently, there's no Run button here because we need to install a Python extension. So if you go over to this, icon hear extensions. And here you want to search for Python, press Enter. And this first result is the extension we want to install. So press on the Install button. And that will install the Python extension. But what is the Python extension? Well, I told you that this will show the Run button somewhere in here. It didn't show it because my file doesn't have a PY extension. So the Python extension searches for PY files. So what you want to do is right click here, rename to dot PY. And now we see that button. We also get this message that we need to select a Python interpreter. So to select a Python interpreter, you either press that button there or if you didn't get that window, what you want to do is you want to go to this icon here, this curly bracket, and then go to select Interpreter. And then you want to select the Python 3.10 0.3 interpreter, which we installed in the previous video. Perhaps in your case, it's another version. So whatever Python interpreter you're using, select it, and then you're ready to run this program using that button. So press that button. And that's the output seven down here. So as you can see, there are two ways to run your Python programs. Either you use the Python command as we did with PY minus three, and then you mentioned the name of the file. Or you use the easier way, which is by using this button. But as you sew, to be able to use that button, you need to name your files with dot PY at the end. And that's actually the best practice. Everyone names their files dot PY. It's like a convention. It's not a requirement, but it is a heart convention. And as you sew, things like extensions, IDE extensions also will work better if you have your files named with dot PY. The other advantage of using this button is that if you had more codes such as four plus nine, you don't have to save the code. You just run it and you'll get to the results seven and 13. So the sum of that line and the sum of that line as well. If you want to create another program, what you want to do is you want to go to File again, open folder, and make sure you have an empty folder or just create one on the fly here. So folder, second project. Double click it select folder, and that will close that current window current project, and it will open the second project. So this one here, again, you create a file. Myprogram dot py dot PY always, select an interpreter using this curly bracket and go there. Choose always the same interpreter that you used previously unless you want to select another interpreter. If you have many interpreters and write some code, run it, and you should see the output here on the command line. With that, I thank you for watching this video, and I'll talk to you in the next one. 8. What is Python Surprisingly?: Let's suppose you are walking in the Amazon forest. In the forest, you meet a tribe and the tribe has a cook. You want to tell the cook that you are hungry, so you need to eat. The problem is you don't know the language. So what you want, what you get is an interpreter. So that is the interpreter. You speak English to the interpreter, and the interpreter speaks Amazonis to the cook. And the cook serves you. The meal. Python works the same. This is you again, and you want to communicate with the processor of your computer. For example, you want to know the sum of three and four. The problem, again, is that the processor speaks a very difficult language called machine language. And this language is very hard for humans to speak or to write. So what we get is an interpreter called C Python. So what is C Python? C Python is the software we installed in the previous videos. So when you download Python from python.org and you install it, what you're installing is actually C Python. It's an interpreter. This interpreter gets Python language from you, and it translates that language to machine language, and it speaks that machine language to the processor. In return, the processor uses the computer display so your laptop screen to display the results, for example, seven, and you see that seven. So as you can see, Python is just like English. It's just a language. The software you install and you use to execute Python is just a software, and it's written in seal language. It happens to be written in seal language. That's why it's called C Python, even though most people refer to it as just Python. When you say, did you install Python? Yes. Well, you're speaking of installing C Python. The Python language itself is just knowledge. It's stored in documentation. If you go to python.org and then go to the documentation menu, then you should see the documentation of Python. So the documentation of Python is equivalent of a dictionary, an English dictionary, such as Oxford dictionary, where the English language is documented. There is one difference, though. In the case where we spoke to the Cook, we used spoken language. To communicate with interpreter in here, we use text files. So we write the language in a text file, and the interpreter reads that text file. Of course, we give the extension dot PY to these text files, but they are still text files. The extension is different. And that's the idea. That's what Python is. So Python is the language. And thanks for following this example, this comparison, and I'll talk to you in the next video. 9. Starting with the Basics of Python: Hi, welcome to a new video, and this is an introductory video of the functions and conditionals section. So now you're entering a more advanced section of Python. Functions and conditionals are some advanced core concepts of Python, and these are very fundamental blocks which you can use to make your programs more intelligent and more manageable. So you make your programs more intelligent by making them take decisions and that you can implement via conditionals. So if your program gets some inputs and you want to think, you want to make your program think if that input is fine or not, and you want to do something if that input is true and something else if that input is false. So you're making decisions in your program through a conditional block. And then you have functions on the other hand, functions are used to wrap in blocks of code, so similar blocks of code. It helps you organize your code. So a function, for example, could convert USD to euros. So this function does this certain things and does it well. So it gets USD as input, and it gives you euros as output. So inside the function, you have those math operations which do the conversion. So conditions and functions are two things you're going to learn this section through examples, of course. So I'll see you in the next video. 10. Variables: Why and How to Use Variables +: Hi, welcome back. Please take a look at this program in here. Do you see any issue with this program? Well the program works well. If we run it, we get seven as output, which is the expected output. So three plus four gives you seven. But there is an issue with the program, and the issue is that we have no idea what three means and what four means. So as programmers, we don't know what's going on in here, and that makes this program not readable. Now, let me show you how I will fix that issue right away by using variables. So I'll delete this entirely and say, spent is equal to three. Donated is equal to four. Total amount is equal to spend plus donate it, and then print total amount. If I execute this program now, I'll get the same output, so it's seven again. But this time, we as programmers can understand this program. So we can give this program to some other persons, some other programmers, or we can go back to this program. Later and we can still understand this program because now we have names for the values, and these are referred to as variables. So spent, donated, and total amounts are all variables. The syntax is pretty simple. So all you have to do is just pick a name from your mind for a variable. So I chose to have spent as the first variable. So this is the amount of money I spent for purchasing things, for example, and then this is the amount I donated. And then I calculated the total amount. So now this program makes more sense. And of course, there are other examples such as items equal to ten and price equal to two total. Price is equal to items times price. So now there is this asterisk here, which means multiplication operator. Print total price, and we get 20 as output in here. So again, we have one variable here, two and three. Now, there are some rules regarding the syntax of variables. The first rule is that you shouldn't have numbers in front of your variables, but you can have numbers in the middle somewhere or at the end, but not in front of them. You can use underscores, such as I did in here, but you cannot use spaces. So this will not work in Python, which means that if you have variables with more than one word, you should use an underscore. It's the best practice to use an underscore. And lastly, you can have as many spaces as you want around the assignment operator. So that will work. But it is recommended, according to the official Python style guide, it is recommended to have one space on both sides of the assignment operator to make the codes more readable. Spaces serve only the purpose of readability here. The same goes for these operators. It's good to have spaces around the operator. For readability again. So now our program makes more sense. We know what's going on in here. We understand the code, and that is one benefit of variables. There is a second benefit as well. Variables serve as buckets to carry data or objects. So ten is a data value, or you can also refer to it as an object. So ten is an object, two is an object, and items is the name of this object, or you can say the variable of this object. And so these names, these variables are like buckets. They are used to carry objects around. For example, let's say we placed ten inside the items bucket, and then we get that bucket and multiply that bucket with a price bucket, which has two inside. So instead of writing ten in here and two, we actually work on a bucket basis, on a variable basis. There is a benefit for this because, for example, let's say we decide to change the value of this to three, and that means items now here will also be three. So three times two, we're going to get six. That's why we don't want to have objects hard codets for example. If this was ten, we run this, we would get the old output 20. So I hope that is clear. Always use variables, and that concludes this lecture about variables. I did go into a lot of details because variables are used in every single program that you write. So make sure you understand them. If not, ask questions in the Q&A, and I'll talk to you in the next video. Thank you. 11. Using The Python Interactive Shell: Hi, welcome back to a new lecture. Previously, we wrote this script, and we can execute it using this triangle button, and we get six as output. So three times two gives us six. So what we did here is we wrote the script in a dot PY file, and then we send that script to the interpreter. So we send the entire dot PY file to the interpreter. But there is another way to run Python code. That is by having the interpreter on demand. Let me demonstrate what I mean by that. So you have to go to the terminal to the command line. This is where you execute operating system commands. So I'm on Windows, so I can execute PY space minus three. If you are on Mac or Linux, you'll have to write Python 3.10 or Python 3.9 depending on what version of Python you are using. I'll be using Pi space minus three and press Enter. So that command starts the Python interpreter. Now, the interpreter, as I said, is on demand, which means the interpreter now is waiting for Python code to interpret it. So think of the previous methods as hiring the interpreter on a contract basis. So you send the interpreter the entire script, and they send you back the output. But here, the interpreter is an employee, let's say, they are on site and they are waiting for your input. They are listening to you. So what you do is you say items is equal to three, for example, you write code and you presenter and the interpreter is listening to you. So it registers the items variable in memory. And you can keep writing code. Price is equal to two, total price is equal to items times price. And if you print total price, you get the output six, which is the same output as that. Now you're probably wondering when to use one way and when to use the other. So should you code in a Python file or should you code in Python interactive shell? So this is now known as an interactive shell. So let me answer you that question. But before I answer you, I want to point out the differences between the two ways of coding. The biggest difference is that the code you write in the interactive shell is not saved. So if I exit this shell now, this code will get lost, and there's no way to save it. And that takes us to the other point, which is that this way of coding is just for throwaway code. So if you want to just simply test things out quickly, perhaps you want to do some math operations such as addition, multiplication, et cetera. And you are not interested in creating a reusable program, then this interactive shell is fine. It's quicker than having to create a PY file and then writing the code there. So I think I've answered the question. You should use dot PY file whenever you want to create reusable programs. And you use the Python interactive shell for quick one liners. So just write one line, maybe another one here. So math operations. Now, I want to point out a difference between the two. Now, another difference you should be aware of is that in the Python interactive shell, you don't need to use a print function. You can just say total price. And you get the output. No need to print out total price. However, in a dot PY file, you have to be very explicit. So if I remove the print function and I execute this program, we will not get any output. So let me execute this program now, but I warn you that we will get an error. So run the program, this is the error. So what happened here? This code is fine, but what's happening is that visual studio code is executing this Windows command inside the Python Shell, the Python Shell only accepts Python code, but not Windows or Mac operating system commands. So this is a Windows command because it is starting it is trying to start the Python program, and it is trying to execute that my program dot PY file. So what you need to do is you need to exit the shell whenever you want to execute a dot PY file. So if you are in an interactive Python shell, and you know you are whenever you see these three arrows, then you want to do exit with parenthesis and press Enter, and that will take you back to the operating system shell, the terminal, the command line. That means now you can run your program. So let me press that triangle button, and we didn't get any error. However, there's no output either, as you can see, because as I pointed out earlier, we are not printing out anything in here. So what the interpreter does is it just assigns 32 items variable. It does the same with price. It calculates the total price, and then here it does nothing. So in order to get output, we need to say print the variable run again and you get six. If you want to go back to the Python shell again, write the Py minus three command, and you go back to the shell, and you can run code again in here. So I'll go back to the shell and that's about the Python interactive shell. Thanks for following. 12. Using the Terminal: Before we go into coding, I want to show you a productivity tip regarding the IDE. Now, this tip is about the visual sudo code IDE, but it will probably apply to other IDEs as well. It's about the terminal, how to use the terminal more efficiently, and this will help you with coding and also with the learning part. So this is what I want to show you. I have my terminal open here. So first of all, what I want to do is I want to delete all the terminals using that icon or the icon could be somewhere in here. So just delete everything. Yeah, the icon show us here now, press that or the other one until the terminal disappears. And then you want to show the terminal again, and you can do that by pressing this button. So that will execute the code. It will create a new terminal window. And then it's good to have a Python shell open on the side as well. So you have both the command line where you run the code, but also the Python interactive shell where you can write quick one liners. So to do that, you want to press this icon. And that will split the terminal. So now we have one terminal here on the left and one terminal here on the right. Here on the right, what we want to do is execute the Python command which opens the Python interactive shell. On Windows, that is PY space minus three, or Macan Linux, that would be Python 3.10 or Python 3.11, and so on. So that will open the Python interactive Shell. Now we have both the command line where we execute dot PI files and the Python Shell, where you run code interactively. That will help with your learning. So let me quickly demonstrate to you if this is working fine or not, so I can have the focus in here. It doesn't matter, and I press that button, but the code will be sent to that terminal. And this terminal here is independent of that. So again, if this is not working, make sure again to delete everything. So no terminals. Then don't open a terminal here. So instead of doing that, let the terminal be opened using that button. That way you make sure that this terminal is connected to the running process of this file, and then you split the terminal, and then you have that commands to open Python. Another tip before we close this video on the command line where the Windows or Mac or Linux commands are sent. So in here, when we run the dot PY file, you can clear the terminal using CLC, write CLC there. If you are on Windows, on Mac it would be clear or Linux as well. CLC press Enter and that will clear the terminal. So this works on the command line, not on the Python shell. Regarding the split window here on the side, you can see how many terminal pans you have. So we have this, which is pointing to this on the side, on the left side, and then the other one on the right. Also just try not to have more than two terminals here because things can get confusing because if you press that plus icon, you're going to have a third terminal which is going to be hidden behind these two and things will get confusing. Make sure you always have two. If you have more, delete everything and start the process again around it, around PY, minus three again, and so on. So with that, you're ready to program in the next videos, and this will really, really help you with your learning. So I'll talk to you in the next video. 13. Simple Types: Integers, Strings, and Floats: Let me demonstrate you something. I'll create the X variable. Store ten in that X, Y variable, store the text ten in that variable, and then create two new variables. So one equals two. X plus X, and some two equals two, Y plus Y. And then print some one and some two. Save the script, don't forget and execute it. This is the output. So we got 20 out of X plus X and 1010 out of Y plus Y. What is my point here? My point is that computers are dump. In order for them to understand you, you have to be very clear, very explicit in what you're going to say through your language, through Python in this case. It's not enough to just say ten you have to declare what that ten is. Is it a number or is it text? That's why in some languages, in most of the languages, we have type declarations. So in other languages, you would say something like int, which stands for integer. So you are saying that this is an integer. Ten is an integer, and this would be like STR Y without quotes. So that tells Python that this is actually a text and should be treated as so. So when Python, when you apply a plus operator, Python will concatenate that text, so it will add ten after ten, and it will make this concatenated string. Now, this is not how it works in Python. In Python, instead of doing these explicit declarations, we have implicit declaration instead, which is this one in here. So when the number is without quotes, is an integer. Well, it can also be a float, but let me talk about that in a few seconds. And if it's with double quotes, it means it's a text. If it's equals to 10.1, for example, that means it's a float. And if you don't believe me, you can use the type function like that X, type Y and type. The type function will print out the type of each value. So it's a class int, a class STR, which stands for strings. Everything in quotes is a string and floats, which stands for float. With strings, you can also use single quotes like that. Save it, and you're going to get the same output. So if your intention is to process text, you need to use quodes. If your intention is to process numbers, so to be able to make mathematical calculations with them, you need to use them without des like that or like that. 14. List Data Types: Now you know three datatypes in Python, you know integers, you know strings, and you know floats. These are simple data types. We also have what is known as compound datatypes, types that are made of different objects. And the list is the most popular one. So in a list, you can actually store multiple objects. Let's suppose you are a teacher and you want to calculate the average grade of your students. So you use Python for that, and you need a data structure to store those values in Python. You need the proper type in Python to represent the grades of your students, and list would be a good choice. Let's create a list. Store it in a variable as usual. Student grades. Equal to open square brackets, close square brackets. So the objects now will go inside this syntax. So you saw that with integers, you'd use a number without quotes for strings to tell Python that that is a string, you use double or single quotes. And with lists, you use this square brackets, so every type has its own syntax. So let's say 9.1 and 8.8 and 7.5. Those are the grades of your student. 15. Using Ranges: In this video, you will become more familiar with lists. So previously, we stored three float data types in a list, but you can store any type of object, not only floats, so we can store an integer such as nine. You can store a string, such as hello. You can even store lists inside a list. You just write a square brackets and then enter the items of that list. So still, this list has three items this integer, this string, and this list. And of course, you can print that list by pointing to the variable associated with the list. And that's the output that we get. No, math operations with lists, what does list support? Well, not much, really. You can do multiplications with an integer, such as two or three, and let's see what's going to happen. I'm going to print out that expression directly here instead of putting that in a variable. So whatever you prefer, you can create a new variable, store that in the variable, and then place the variable in the print function or directly place this expression in the print function. Both will work. So if you run that, you're going to get this output. So that's the same list repeated three times. If this was plus, this is not supported because Python doesn't know what to do with a list and an integer. So it gives you an error type error only can concatenate lists to lists. So it can concatenate lists to lists. So if you do student grades, plus student grades, that will also work. So run that and you get this results. The list repeated two times, which is the equivalent of that times two. So again, we're going to get the same results here and there. Lastly, there's also a way to auto generate lists of integers that have a certain order. Let's say you want to have a list 1-10, one, two, three, four, five, six, seven, eight, nine, ten. How can we do that? Well, of course, one way is to write that down, but there is a better way, and that is to use a range. Range is another type of object, just like we have lists, integers. We also have ranges. So range zero and 11, and let's run student grades to see what this variable has now as a value. So run that, and this is a range object. So not much to see yet. But if you convert this into a list and run again. Lastly, we're going to get that output. So zero, one, two, three, four, five, six, seven, eight, nine, ten. So now student grades is a list object. And this list keyword here is a class. So it represents the last data type, and it is used here to convert a range data type into a ist data type because a range displays simply like this. So this is not very beneficial to see the output is not so clear, so we convert it into a least data type. And so how does it work? Well, it starts from zero up to the number before this number, which is ten, so zero to ten. That's why we have zero to ten. Of course, you can have anything here. So one to eight, I would have to write nine to get one to eight. So at least one to eight. You can also have another argument here, two, and let's see what that changes in the output. So we get these results. That two is the step. So one, three, five, seven, it means that you start from one, and then you move by a step of two. So one plus two, you have three, three plus two, you have five, five plus two, you have seven, seven plus two, you have nine, but nine is not included in the range. The range is up to eight, so the list will end up at seven. Of course, you can have any steps here, like three, and you'll get different results. So that was some more advanced information about lists and also ranges. With that, I thank you and I'll talk to you in the next video. See you. 16. What are the Attributes of Data Types: Okay, so you know strings, you know, floats, you know, integers, you know, lists. Okay, so you know, data types. But how can you actually do something in Python? What can you do with these data types? Well, to answer your question, you should look at the deer command. Well, let me now start to use the Python shell a little bit more to do things quicker. So I'm going to split this into two. This is for executing the Python file, this is for the interactive Python Shell. So what can we do with list? You can find that out by doing Deer. Dear is a function in Python that will give you all the things you can do with a specific type. So with a list, in this case, all these here are attributes of list. You can do the same for checking int. You can do the same for checking float, dear float, dear STR, for example, let's stop at SDR before we go to list. With strings, you can do, for example, you can turn them into uppercase using these methods. To find out what upper does, you want to use help STR, that is the type that has the attribute upper. Now, attributes are all these and they can be either methods or properties. You don't know that until you check with help. So that is a help documentation for the upper method. It's a method, as you can see here, Q to quit and go back to the shell. Then let's go ahead and use that. Hello, that upper. You use a method with round brackets with parentheses. And that will return the capitalized version of hello If we use Title instead that will capitalize the first letter only. Of course, you can use variables. And you get the same output. Now, what do we have for lists? How about calculating the average of the student grades? Let's do that in the next video. 17. How to Find Out What Code You Need: To calculate the average of these grades, we want to see if a list type has some sort of mean or average method that allows us to get the average of its values. For that, we go to check with deer list. List is the name that represents all lists. So that is a type, and this is an instance of that type of list type. Dear list. And let's have a quick look here. Do you have a mean or average method? I don't think so. So there's no method of the list type to allow us to calculate the average of list values. However, that doesn't mean that doesn't exist a mean method in Python to do that. Man or average is not a method, but it can be a function. You remember the print function? So print like that, you see that print doesn't need the dot notation to be used. Like for example, the upper method did need a dot notation because upper is a method, attached to the halo type. And print is a function. It's an independent function that works with many types, not only strings, not only integers, floats. You can print anything with print. That's why it's not attached to a specific type. So where do we see a complete list of functions that we can use? You can do that using the again, underscore, underscore, built ins, underscore, underscore, close parenthesis. And that is a complete list of what you can use built in functions. So let me see for a mean function or an average function. No, it's not there, but there is a sum function. So what we can do is, let's say my sum, don't use sum as a variable name because you can see that sum is a reserved keyword. So sum student grades, that will give us the sum of these three numbers. Then want to count how many items there are in that list. So do we have a count something there? Maybe not. Well, I know there's no count method. But we have this len, which means you can check what it means. So return the number of items in a container. So a list is also referred to as a container. Let's say length, equal to length, student grades. Then finally, we can get the mean, which is my sum divided by length and print out the mean, save that is the mean value of all those three numbers. 18. Dictionary Data Types: So you are a teacher and you wanted to calculate the average grades of your students, and we did that using this algorithm here and this data structure to store the grades. The problem here is you don't know which grade is of who. So while a list is a good data structure to store an array of items, it's not good enough when these items have some sort of identity attached to them. In that case, you want to use a dictionary. Let's say student grade, curly brackets. That's a syntax for a dictionary. And then you use names of your students. Let's say Mary a column, make some space or no space, whereever you prefer, but it's good to have a space there to make it more readable. And then you write the grade of Mary. Let's say S 8.8 and John column, 7.5. The difference between the dictionary and the list is the brackets, different brackets. And then this is considered an item in a dictionary. This is considered an item in a list. So items in a dictionary are made of keys. This is a key and values, this is a value. A list would be more appropriate if we had to store, for example, an array of temperature values. Let's say, Monday, had these temperatures Monday temperatures. And lastly, how do we calculate the average when we have a dictionary? Since these are pairs of keys and values, you can't just make the sum like that. You need to specify the sum of what you want to get. So student grades. And if you check their dict for dictionary, you'll see that dictionaries have these values, which is a method. Dict the values it is a method, and it provides a view of dictionary values. In simple words, it gives you the values of a dictionary. So if you get this dictionary, queue for quit here, paste it here and see student grade that values. That will give you this data type. It's still a data type. It does look like a list. It's not exactly a list, but it behaves like a list with these three values there. It's a dict values type. That method produces this type. Therefore, you can add that in there, don't forget the parenthesis, don't forget to save and don't forget to execute to get the output and this is the average value of dictionary values. To get the keys of dictionary, just do keys. And you get this died keys type with the keys of the dictionary as items of that died keys array. 19. What Makes a Programmer a Programmer: What makes a programmer a programmer? In other words, what are the things you need to know to be able to program any computer application? This is what I'm going to tell you in this video. There are three things you need to know to program, to code any program. And the first is you need to know the syntax. For example, you need to know that to be able to print out some outputs, you need to use prints followed by parentheses, and then you put the input inside those parentheses. So that is part of a syntax, knowing whether you want to use parentheses or commas, et cetera. That's the first thing. The next thing is, let's say we are building a program which calculates the average out of a series of values. Then you want to know what data type you need to use to represent this data. So, for example, if you have a data as names of students followed by the grade of each student, then you know you need to use a dictionary because a dictionary is made of keys and values. So the correct data structure here would be a dictionary. But if you just had values without student names, then you'd think about a list because a list is just a series of items, values without keys. So data structures, you need to know data structures and you need to know the syntax. These are two things. The third thing is you need to know the algorithm you need to use to produce the expected output. So in this case, you should know the methods you can use or you should know how to create these methods if they don't exist. So in our example, you need to know how to create this average method. So these are the three things you need to know about making any program. These are the fundamentals. So I hope this makes it more clear the way to programming, and I'll talk to you in the next videos. See you. 20. Tuple Data Types: This one here is a list. And now it is a topple. So a tuple is just like a list, but with parentheses, not square brackets. If you print it out, of course, you'd get the same representation as in here. So 14, five, 145. However, the brackets and the parenthesis is not the only difference between lists and tuples. In fact, this is just a difference in syntax. The real difference there is that tuples, such as this one in here are immutable and list such as this are mutable. What that means is at the last Monday temperatures, two, you can add more items to the list using, for example, the append methods. So if you check Monday temperatures to now, you'll get a list mutated. This mutability makes is very dynamic. You'll see later how when we do these batch operations and each operation, we are adding items to the list as we generate those items, those values with some functions. But this is not the case with tuples. If you try to append in a tuple, you'll get an error because a tuple doesn't actually have an append method at all. Likewise, it doesn't have a remove method like the list does. So four is not there anymore. Tuples, however, have the advantage that they are a bit faster than lists, but you should think what to use. So whether to use List or topples, you should think if the array you are creating is going to be changed during the course of the program or not. So for now, I'm not going deeper into topples and is. But when we create these ten applications during the course, you will understand the main differences between the two by seeing how they work in real programs. 21. Using Data Types in the Real-world +: Okay, so you now know about some of the most important Python data types, but I bet you are still confused how these datatypes are used in the real world. Normally, for example, normally you'd have these data stored in an Excel file or a text file. So does it make sense to write them in a Python dictionary like that or like that? List? No, it doesn't. There are actually ways to automatically load the data from your Excel spreadsheet to Python to create that dictionary. You still have to create the dictionary, but you don't have to type the data in the python dot py file like I did here. You're going to use some specific Python extensions to load the data in here. Then you process that dictionary as we did in here. But don't worry. I'm going to cover that and we're going to have some nice applications later in the course in the applications part. Stay tuned. 22. Operations with Data Types: Let's suppose you have a list of grocery items and you have made a program, and you have stored those items in a Python list with square brackets. Now, in your program, the users might remove and add items from that list. So remove and add are two examples of operations that you can have with lists. So list is a datatype and it might have different operations, which you can apply to a list data type. And then you might have some text somewhere else in your program, and you can capitalize that text and so capitalization is another operation that you can apply to a stream data type. So each data type has its own operations. So that is what you're going to learn in this section. So this was an introductory video. I'll see you in the next video. 23. Error Messages in Python 3.10: In this lecture, we're going to look at what's new in Python 3.10 regarding error messages. Python 3.10 was released in October 2021, and it does have some improvements regarding error messages and also other improvements as well, which I'm going to talk in next videos in the next sections. So the error messages, let's suppose you have an expression with lots of emphasis. For example, you want to have a string and you want to replace the I character with a Y character in that string. But if you miss a parenthesis and you run the program with Python 3.9, what we got is the syntax error, of course, because the syntax is not correct, but the error is not that explanatory. So we get the syntax error unexpected EOF while parsing. So you still don't know what you did wrong in your code. So you have to go back and read it again. Now, compare that to Python 3.10. So if I switch to Python 3.10 as interpreter and run the code with 3.10, this time, the syntax error is more clear. So syntax error, this parenthesis in here was never closed. So that one. Now we know that if we start a parenthesis here, we should close it at the end. This is the first parenthesis, the open parenthesis. I should have a closing parenthesis. So let's add that. Another example would be if you had a list, for example, one, two, and then you miss a comma, and if you run with Python 3.10, you're going to have again this syntax error invalid syntax. Perhaps you forgot the comma, and it points us with these arrows in the place where the comma should be. If you compare that to 3.9, it's not the best explanation. It does say invalid syntax, but it doesn't explicitly say that we have a comma missing here. Still, Python 3.10 is better in detecting missing commas. The idea is that in Python 3.10, you get the syntax error and you also get some extra information. Let's close this video with a third example. If you make a typo, let's say you wrote real pace instead of replace, and let's have the comma here. So everything is right, except this typo here. So if you run this with 3.9 first, you get this attribute error. It says that string object has no attribute replace. So today does not have the attribute actually a real pace. And you start wondering if replace is not an attribute of strings at all. So compare that with 3.10, 3.10 run, and this is the attribute error. So did you mean replace that is a very explicit error and it helps us to quickly fix this error. So that's what I wanted to compare Python three with Python 3.10 to emphasize the differences in regard to errors. Now, in the course, we're going to have a dedicated section on errors, so how to handle them, how to read them, how to not get frustrated with programming errors because every programmer makes errors, so you have to know how to fix them. For now, you're still a beginner, so keep on watching videos and you will become better and better in Python. See you in the next video. 24. Making More Operations with Lists: Let me now make you a bit more familiar with list datatypes by showing you what you can do with them. You know that already that what you can do with them, you can check with DR List. You can ignore the attributes that start with double underscore and end with double underscore. They are basically attributes used by Python internally, and rarely you're going to have to use them. So for now, you can just ignore them and focus on what you're going to actually use, which is this set in here. Let me open another Python Shell and I'm going to apply some operations to that list in this Python shell. So we can see what methods we can apply in this window and we can apply the methods in this other one here. And I don't just want you to show you what this does in the dark. I want to show you the way you can find out yourself what these things do. So always use help function. List, let's try the append method. Now, I'm going to type the variable, but you don't have to type all of it. Once you have started to type that variable name, you can use tab, and that will auto complete the variable name. Then use a dot notation and append, and then two parentheses. So inside the parenthesis, you'll see that this takes two Arguments. Actually, it's only one argument. It's only the object itself. Self is referring to the list itself, and object is actually what you want to append to that list. Let's say you want to append 8.1 like that, if you check Monday temperatures, you'll see that it now has one more item. So that is the syntax of append. You always ignore self because self is automatically passed as an argument to that method, and self is basically the actual list itself. Let's try another method. Que here to quit, help list, clear. How does it work? Well, in this case, you see that it doesn't get any arguments. So Monday temperatures that's clear just like that. And what it does, it just clears the list, it deletes all of its items. Let me also try index and leave the list for you to try. Index gets actually a value, a start, and a stop, and it returns the index of the value. So what is an index? Let's try it out dot index, the value with value what Python means is one of the values of the list. Now, since we have a list without values, I'm going to recreate the list again like that. Now this is our list. Let me try index with parenthesis and the value, let's say 8.8. That will return one. Why? That's because lists have index sync on the background. Even though we don't see it, each of these items is associated with an index. The first one has an index of zero. The second has an index of one, and the last has an index of two. In this case, and so on. Now in this particular case, we also see this argument and this other one for the index method. However, if you don't want to pass those values, you can just pass one value. So like I did here, 8.8, that means 8.88 will be the value, this by default, start will be equal to zero, and stop will be equal to this value. So what is start and stop? Well, when it's zero like it is by default, that means you are looking for 8.8, starting from the first item of the list. So the interpreter will start the search from the first item, so the item with index zero, and we'll look for 8.8, and it will find it, and it will tell you that it has an index of one. However, if you want to tell Python to start from the item with Index two, let's say, so to start a search from here and forward to the right of 7.5, which happens to not have any more items. But anyway, so you are skipping this part of the list. In that case. The interpreter will tell you that 8.8 is not in the list with that start. You also have the stop, which is by default, this big number. So if you want to limit the search on index on the right, you can do that, too. But by default, you're going to keep that zero. And that will tell you that the number has that index. More about indexing in the next video. 25. How to Access List Items: Previously, I showed you that in order to get the index of an item, you can use the index method. Now, how can we do the reverse? How can we get an item given its index? Well, for that, we need to look one more time at the list of attributes that we can apply to list. And I know that we can use the underscore get item underscore underscore method. Okay, I know I told you earlier that these methods rarely you're going to use, and in fact, we don't need this method for what I'm going to do now, but let me explain why in just a bit, you'll understand. This is a very secret of Python. So let me go ahead and use get item with double underscores, and of course, it's a method, so it needs this round bracket parenthesis. So let's try to get the item with index one. Which would that be? Well, 8.8. Now, the secret is that you don't have to use that ugly method there with those double underscores. All you have to do is use this syntax, call the variable name like that and then add open and closing square brackets, and then inside them, just enter the index. That will give you the value, the item for that index again. Even though you're doing this, Python on the background actually is calling this method and is passing this item, this value as an input for that method. So this is actually what's going on on the background, but Python lets you do it in a better fashion like this in here. 26. How to Access List Slices: I have a list of five items here. Let me show you why use a n function and you see that it really has five items. Now, besides accessing single items out of your list like that item with index three, zero, one, two, three, 6.6, you can also access portions of the list. Let's say, 1-4, that will give you another list. So the outputs of this is also list, and it's going to contain the items with Index one, index two, and index three. The upper limit, it's not included. It's never included in a Python slice. So this is a slice, and this is the output of the slice. Let's try to get the first two items of the list. The first two items have an index of zero and one. So we'll start with zero. Since we also want the item with index one, we're going to write two there so that we get one. That is the output. So the index two is not included, 7.5 is not included. You can also use a shortcut for that. You don't have to type zero if you meant to get everything starting from the first item, and that will give you the same output. Similarly, if you want to get, let's say, the last two items, you can start to count zero, one, two, three. Three, start from three, this has an index of four, so we're going to write five there. Even though we got the expected output, you'd better be using the shortcut for that. So this is more intuitive because it tells you that you're extracting from item with index three to the last item of the list. So without knowing how many items there are in the list. Similarly, here, you're extracting from the very first item to the item with index one. Now, for big lists, when you want to extract the last items, it may make not much sense to count from the beginning, one, two, three, four, five, six, and so on. But Python has another system of indexing, and I'll show you that in the next video. And 27. How to Use Negative Indexes: So how do we get the last item of this list? Well, you can do that by referring to the list and then square brackets and then refer to the index of the item you want. So 9.9 has an index of zero, one, two, three, four, four. Okay. But a smarter way is to use a negative indexing, which means instead of counting, you can just write minus one and you get 9.9. So each of the items of a Python list has two indexes, a negative and a positive index. So minus one for this, minus two for that, minus three, minus four, minus five. So minus five is the first item, actually, 9.1. And of course, you can do list slicing using negative indexing. Let's try to get the last two items. So to do the slicing, you have to put the index of the first item of the slice. So the first item of the slice is 6.6 and 6.6 has negative index of two. Use a column, and then you don't want to assign anything here because you want everything that comes after 6.6. So just like that, and you get the tail off the list. So similarly, you can do minus four minus two, for example, that will give you 8.8 minus four minus three, and minus two is not included in the slice, because I told you that the upper limit is never included in the slice. So you only get this and that. You can also start from the beginning of the list to get 9.1, the first item like that. 28. How to Access Characters & Slices in Strings: To your surprise or not, strings also have an indexing system. The good news is that they have exactly the same system as lists. So they have positive and negative indexing, and you can slice them and you can access items from them. Let me make a quick demonstration. String hello that will give you the string E, which is still a string. Hello is a string, E is also a string, a negative indexing, and also slicing. One cool thing you can do is let me get this list. So it's a list containing different types of objects. And what you can do is you can access guess it? Well, that's the yellow string, so the first item of the list. Then you can use a chain indexing, such as, for example, if you type two there, guess what you're going to get. Well, you're going to get the first L because that has an index of two, so zero for H one, for E, two for L. Because this part here is a value on its own, and this other part will get the item with index two of that value, which happens to be a string. It is as simple as that. 29. How to Access Items in Dictionaries +: Do dictionaries have the same index system as list and strings? Let's find that out. I have this dictionary here on my Python shell, student grade. So let's try to get the second item, maybe. Nope, it says key error, one, which means that the dictionary doesn't have a key named one. So what keys does dictionary have? Maybe the same key. Yes. So dictionaries, instead of integers, they have keys as indexes. So a list would be access. The items of the list would be accessed via integers, which start from zero and end to the last item of the list, the index of the last item of the list. With dictionaries, this is different as you can see, and this is actually what makes dictionaries a dictionary. Let's see another example of how useful this is. Let's say you have this dictionary, English to Portuguese. It's a real human dictionary. You have some words there. Let's say in Suva in Portuguese and sun will be so. Sorry, I've got a typo there. Codes. So now, if you want the Portuguese version of sun, you write that, and that will give you that version. So having integers as indexes in this case, would be very useless. So every use case has its own data structure to be used in Python. 30. More Python Basics: Functions and Conditionals: Hi, welcome to a new video, and this is an introductory video of the functions and conditionals section. So now you're entering a more advanced section of Python. Functions and conditionals are some advanced core concepts of Python, and these are very fundamental blocks which you can use to make your programs more intelligent and more manageable. So you make your programs more intelligent by making them take decisions and that you can implement via conditionals. So if your program gets some inputs and you want to think, you want to make your program think if that input is fine or not, and you want to do something if that input is true and something else if that input is false. So you're making decisions in your program through a conditional block. And then you have functions on the other hand, functions are used to wrap in blocks of code, so similar blocks of code. It helps you organize your code. So a function, for example, could convert USD to euros. So this function does this certain things and does it well. So it gets USD as input, and it gives you euros as output. So inside the function, you have those math operations which do the conversion. So conditions and functions are two things you're going to learn this section through examples, of course. So I'll see you in the next video. 31. How to Create Your Own Functions +: Earlier in the course, we were looking for a mean or an average function that Python might have to allow us to make the average of the items of the numbers of a list. And we found out that Python has some more fundamental functions such as length to get a number of items of a list and sum to make the sum of the numbers of list, but it doesn't have a mean function. So we ended up doing this. We had this list. We calculated the sum using the sum function, calculated the length, so the number of items using the length function, and then did the division between sum and length to get the mean. However, the fact that Python doesn't have a mean function doesn't mean we cannot create our own mean function. What we're going to do now is we're going to create our own mean function. To create functions in Python, you use the def keyword and then pick a name for your function. The name has to follow the same naming rules as with variables. So it cannot start with a number, it cannot start with a math operator. Let's say mean then you use round parenthesis and inside those and the first line ends with a column. Inside the parenthesis, optionally, you can input some parameters of your function. Parameters, in other words, is input that your function will get and that will process that input and that will produce an output. The input in our case would be a list. However, here you have to give a name, following again the same rules as with variables. Let's say my list. Okay, then you want to press Enter there, and you see that automatically visual studio code. So the editor indented the next line with four spaces, one, two, three, four. So that's what the syntax requires that after the first line, so after you have defined what name you want for your function and what parameters you want, you have to indent the next lines. So either your editor will do it automatically, but if it doesn't do it, one, two, three, four, indent four spaces in there. You can also make it with one space or just one space. Would also work, but it's recommended to use four spaces. Everyone uses four spaces because it's more visible the indented code, so it will make your code more dredable. Then you can start to calculate the mean. Let's say the mean. I'm going to call it like that so I don't confuse it with the function name. That would be the sum of my list, divide by the length of my list. And next, what we want to do, we want to use the return keyword. And that is followed by what you want to return. Well, we want to return the mean. Now, save that. And let me open a terminal. I want to execute this script now. So let me show you what will happen. Nothing will actually happen. Nothing happens because what Python does is it just reads this definition. This is like a blueprint. You have declared what your function should do, but you didn't tell Python to execute your function. To execute your function, you want to call the function pass an input value for that parameter that you defined. As you want to print out print, open parenthesis there, close parenthesis there, save, don't forget, and execute. And that's the mean of those three numbers. So like that, I can easily try this out with many input values. Just like that, I don't have to rewrite anything in here. That's the beauty of a function. So you can see the similarity here. Just like we use the sum function, we are using the Mint function in the same way. So sum gets this input value Man gets this input value. This happens to be a variable. This happens to be a direct value, but it doesn't matter. If you check the type of mean, type mean and type of sum, what you're going to see is that Mean is a function. So that was printed out. This was printed out by this. So mean is a function and sum again, it's a function, but it's a built in function. So it's built in in the Python interpreter. It was designed by the Python core development team, and this function was designed by me, the programmer. So that is how you create and call a function in Python. 32. When to Use Print and Return +: Something to point out is that when your function doesn't have a return statement, save, execute, it implicitly returns a non object. None is a specific object in Python, which means nothing. It's not an integer, it's not a float, it's not a string, it's just none. It means nothing. Python, what it does is if it doesn't find the return statement on the background, it does this return none. So if you execute that, Oops, an indentation error. That's a good thing. You see that all this block here has to be the same level of indentation. If you indented four lines here, you have to indent four lines in here too. So indentation has to be consistent. That looks right. So we got the same outputs, none here and none there. Some people do this mistake. Instead of returning, they use print. Instead of using return, they use a print function. The mean, which works half the way. So it still returns the value and it also returns none. So what's going on here is that when you call the function here, Python will execute all these lines, so it calculates the mean, then it goes to the next line. So line by line, it will print the mean, so it will print out the mean in here, and then it will look for a return statement. It doesn't find it, so it will return none. The problem with this is that if you try to do some other operations with your mean value, let's say, my mean is equal to the mean function zero, three, and four. Okay. And I want to print out my mean plus ten. So I would expect that this would give me the value of seven is the sum divided by three, two point something plus ten, 12 point something. But let's see what this will give me. So this will give me a type error instead. I tried to add the non type, which is none. So this is a non type. That's the type of this value. It's trying to add that to ten. So my mean is none because it returns none. A interpreter will try to add up that to ten. That's not possible. So that's why you shouldn't use print. If I replace that with return instead, remove the parenthesis, save, execute, that will give me 12.3. That is the average plus ten. However, this doesn't mean you cannot use print in your functions. You can actually do that. Let's say you just want to print some information. Stud it. Function, study, and execute that. You get the output of print in here, and then Python returns the mean. You get the mean, you store it in here, the output of your function, but the value of the function is always what you return in here. If you see that So always use return in your functions unless you have a very special reason to do so. 33. Introduction to Conditionals: We define this function in the previous lectures, which is able to calculate the mean of a list. However, what happens if instead of passing a list as input, we pass a dictionary. Student grades is this dictionary here. Let's see what's going to happen. Well, it says an unsupported operand type. So an error will occur with the sum function because it will try to add up strings and integers, and this function is not designed to process dictionaries. It's designed to process list. So how can we make this function to process both lists and dictionaries? We can do that using conditionals. Let's see how to do that in the next videos. 34. Using the If Conditional: This function returns the mean value of a list, but we want to make it more intelligent. We want the function to return the mean even if the input value is a dictionary. So when the input value is a list, it will going to apply a specific algorithm and return the specific value, which is a mean novel is when it's a dictionary, it's going to check if it's a dictionary and apply the corresponding algorithm that calculates the mean value of a dictionary. So we know that some Monday temperatures divided by length of Monday temperatures gives you the mean of the list. Similarly, student grades, which is a dictionary, its values, the sum of its values divided by the length of student grades dictionary, will give you the mean, so we want our function to check and make a decision. This is a parameter. Let me change it to value. Value is a more meaningful name since what we are processing will not only be a list, but it can also be a dictionary. And then under the function, everything has to be indented. You can see the whole body of the function is indented. The conditional block that I'm going to write here is also going to be indented. It starts with if you remember, we use a type function earlier in the course, which returns the type of an object. For example, this is a dictionary, an empty one, but it's still a dictionary. So what you can do here is you can say, I type value, double assignment operator, which means equal. It's a comparison operator, I checks equality. If that is a dict, a column, enter, and it has to be indented with four spaces. So you see it's another level of indentation. It's one here for I, and this is for the function. So here, the mean will be equal to sum of value that values divide by the length of value. So this is a dictionary, dict dot values and length of the dictionary. I have to close the sum function call there like that and enter if you are done with I block. So if that's all what you want to check, then you say else, and we have this code, which has to be indented under s as well, and that's it. Let me try this. So with student grades, the dictionary as input, we got this value here. If I used the last Monday temperatures, it's going to give me the other value, which is the mean of the Monday temperatures. So that's an if and else conditional. But let me explain it line by line in the next video. 35. A Conditional Explained Line by Line: So what is going on in this script? Let me explain it line by line. Python executes the function definition, but it doesn't do anything because it's just a function definition. Python does things when it finds a function call, such as this one in here. So here we are calling the function and the input value for that function will be monday temperature, which is equivalent to this list. This list will go and be stored in this variable. So a value is equal to this list. So what happens is that the interpreter will check if the type of that list is died. If that is true, then it will execute this line here. I will assign the output of this expression to the mean variable. However, this is not true in this case because type of the list is not addict. So Python will not execute this line. It will go to the next line. So if that was not true, then it will do this thing here. So the mean will be equal to the sum of the list divided by the length of the list, which is 9.26 something. And so this is the current value of the mean, therefore, here the indentation ends. So return is outside of the I and else block. You can see here. It has to be outside. So the conditional block ends here and the current value of the mean will be returned by the return statement. So you get that mean value for that list. If this was student grade instead, what happens is that this dictionary will be stored in value and if type of value is dict, yes, it's dict. The mean will be equal to that. So to the mean of the dictionary. And if this condition is true, this is executed, and Python will ignore everything that is under else. I said everything that is under ls, which means everything that is indented under else. So the children of else so to say, return of the mean is not a child of ls. It's not indented under ls, it's independent. It has its own indentation level. So therefore, the current value of the mean is this one in here. So return the mean, we actually return the mean for the dictionary. That one in there. 36. More Information on Conditionals +: Now, this conditional block happens to be inside a function, but it can also be outside a function such as this. And let's say three greater than one, print greater else Print, not greater. And you'll get greater. What a conditional block checks is actually checks if this is true. So true is actually another type in Python, just like integers and leads and strings. True is another type. So that is actually the equivalent of if true, print greater, else, print, not greater. So true is always true. Similarly, type three, for example, equals to t will return true. So that's what we're doing here as well. However, there is another way which is considered better in Python to use is instance is instance value, and you want to check for dictionaries here like that. Execute and you're going to get the same output. I instance, three int, will get you the same output. You can use either one, but for some advanced reasons, which I'm not going to explain right now because it's out of the context. At this point, of course, it's better to use is instance. Now, you saw this example where I used if three is greater than one, and I printed out greater and not greater. We could also have these three cases three is greater than one, three is equal to one, and three is less than one. In that case, if an else is not enough, we need something else. I'm going to show you how we can do that in the next video. 37. Using the Elif Conditional: I've got these two variables here, each of them has a value and let me write a condition that will do something different depending on whether X is greater, equal or less than Y. I X is greater than Y, print. X is greater than Y. If X is equal to Y, print A S is equal to Y. And so what remains, what is the conditional? If X is not greater and it's not equal, well, s. So if you had more conditionals to check, you can continue with if that and L this and that and so on. But if you are done, you can use Ls. Print, so it has to be X is less than Y. And so we get X is greater than Y. 38. White Space +: In this lecture, I'd like to clarify the use of white space. So when to use one white space, when to use more than one and when not to use white space. To explain that to you, I've got a script here with three parts. Each of the parts will do the same thing. So the first one prints out A, aA, and three as, and then B, here, and then C. So the first one, here I typed in one, two, three, four, five, six, six spaces. So that will work. As you can see here, you get the output correctly, but it's not a good practice. Even though that will work, it's not a good practice because the code is not very readable. So that's a problem with this first block. And here in the second block, I fix that. The space here is just right. Basically, you want to separate things with spaces. When it comes to operators such as the comparison operators or plus or minus or multiplication, the code will work even if you don't have any spaces like that. However, to make the code more readable, it's better to have some spaces between operators as well. The space between I and a number is a must. If you have that, the code will not work. You'll get an invalid syntax. However, no space between operators is fine. So that's a problem in this block here that you have this expression without spaces. In some particular cases, sometimes, I don't use spaces in the videos because I want to show you the text in greater fonts, so I have to sacrifice with less spaces so that I can fit more texts in the screen. So unless you have a good reason to do so, please use spaces one space. Then here that is fine. One space here, one here, and one there, and then after the column, this is what you should know. I told you already about indentation. After a column, you always have indentation. Indentation means at least one space. This would also work like that, but a good practice is to have four spaces, four. That's correct. And when you have more code in your script, it's good to separate things with break line to separate logics. So if you have a conditional block there, you have to write them line by line. No break lines here like that. That would also work, but please don't use break lines to make your code more readable. However, once the conditional block ends, you have another logical block there's no clear cut rules here, but just use the logic. So I thought it's good to have these print functions without brick line between them. So here, if I would add another function, I'll make a brick line and then create a function here and so on. And of course, use indentation for functions as well. So after the column, always comes the indentation. That's it more or less about space wide space in Python. 39. More Python Basics: Processing User Input: Welcome to a section of the course. Here you're going to learn how to interact with the user via your Python program. So your Python program can get input from the user. It can prompt the user for some inputs, and the user enters some input, and the program so your Python script will get that input, and it will process it, and it will give some results then. So let's see in this section how you can get input from the user, process it and produce some output. I'll talk to you in the next video. Thanks. 40. Learning More on User Input: As you know, from the previous lectures, we have defined this function, and here we are calling it so it checks if the given temperature is greater than seven and it returns warm if that is true and cold if the temperature is equal to seven or lesser than seven. That's fine. But what is the use of this function in a real life setting? Like, who is giving this input? You as a programmer, you are writing this function for someone else so that they can use it. But you don't expect them to edit the Python file like to have editor like Visual Studio code or other editors. And then you cannot just tell them to go to line seven and change the value and then execute that code to get different outputs depending on the value. So how about prompting the user to enter a value? And then the user types in the value, and then we get that value and process it in our function. In that case, we get that value and put it in here in the function call. Let's do that. So we've got a function there. We want to get a value from the user. To get a value from the user, use the input function. The input function gets an argument, and that is the message you want to show to the user on the command line. For example, enter Enter temperature. Maybe put a column there if you like, you can write whatever you like. Let me save the script and execute it. You see now I executed it, and this input function, what it does is it freezes the execution of a program and waits for user input on the command line. So if I input something here like seven, in this case, what's going to happen is that this expression here will be equal to seven. However, because we didn't do anything here, nothing will happen if we print out this value for example, seven, you'll get printed out the value of this, which is seven. So there you can put anything you want. Hi there, and you get high there, printed out. What out suggests is instead of printing this out, you'd first want to put it in a variable. That would make it more readable. So use your input, and then you can do whatever you want with that variable like lower it. So print out the lowercase version of that. Hi him. So you get hi hi with lowercase letters. Okay, back to our function. Let me now try to print out the weather condition function output with a value of, well, user input, whatever the user enters as input. So I'll execute the program now. The program will ask me with enter temperature. The program will ask me to enter a temperature, so the execution is frozen at this point. This line has not been executed yet. It will be executed after we give a value here and press Enter. So let me write down six. Let's see what we're going to get this time. We get an error. Let's read the error carefully. It's about file Basics dot PY, which is our file, okay? The error happened at first at this line here. So here, print weather condition, user input. When Python tried to execute this line, it couldn't do it. And why? Well, you have to follow the error. So still line basics, that's line two. This line. So when Python tried to execute this line, that line called some other things in the script. And the error was in this line two. So when the function call tried to call the function, it tried to execute this line. So if temperature it tried to compare five with seven. And then it got this error when it tried to compare five with seven. So when it tried to execute this line, in other words, see what it says. Type error. This operator is not supported between instances of string and integer. So string and int, which means this was a string, and this was an int. So our user input was seven was passed in here, and that was compared with seven. It seems that our input, the user input was a string, and that is true, and that was the point I was trying to make here because whatever input, the user writes in here, even if it's a number, Python will actually convert it to a string. So seven, in fact, will be converted to a string like with quotes or double quotes inside Python. But that has an easy fix. What you can do is you can convert this value, which is a string seven, you can convert it into a float. Be careful with parenthesis. So float is a function. It has an open parenthesis in here and it has a closing parenthesis in here. Input is also a function with its own opening and closing parentheses. So now if I do that, the temperature five, I'm going to get the correct answer. And let me be transparent with you. Let's again, input get user input, enter some input. Let me now print out the type of user input. Execute and six, you'll see that six actually is a string. That's why I am converting it into a float so that six this time will be a float actually, which looks like this. You can print out the actual number here, actual converted number, the float version of the number, execute again, 6.0. You can also use int here if you like, six, so you'll get six, which is equal to 6.0, of course. But floats would be a better choice because I can show you why. If you enter 6.3, for example, It will not be able to convert it because that is like doing Int, 6.3 in double code. So Int will get confused, will not know how to convert that into an integer. It does, however, convert six if it was a simple six without a decimal point. Float will convert sorry, both six and 6.3. That's how you use user input in Python. 41. String Formatting +: How would you make a program that behaves? Like this, it asks you for your name, and you put your name as a user, and the program will greet you will output a message hello and your name there and also an exclamation mark at the end of the string. Well, you do that with two things. First, you need the input function to ask the user for input to prompt the user for input, and then you need string formatting. This is how string formatting looks like in Python. So in the first line, we're getting the user input, storing that input as a string in user input, and then we create a variable. In that variable, we will store the message we are constructing. And this here is a string formatting expression. So we want to print out hello and then have a space, and then we want to print out the name of the user, so the value that the user inputs. And this here, percentages is a special string in Python. Then we have an exclamation mark, which is a normal string. And a double quote. So this is special here. And then after the string, you don't want to put a comma, what you want to do is use this percentage operator and then use a variable. Now, the value of this variable will go and replace the percentage S. So what you get instead is hello and your name there. Now, this method of string formatting by using this percentage S here and percentage operator in here, this is valid for Python two and Python three as well. Now there is another method that was introduced in Python 3.6. So the method I'll introduce now will not work if you run it with a Python version earlier than 3.6. The method goes like this. Let's store the entire string in a variable again, so it will be a string with double quotes or single quotes, whatever you prefer. I'm using double quotes. So hello, and you use these curly brackets. And inside that, you put the name of the variable which value you want to be put in this place? Now, this is not all. So if I save this and execute the code and I say, Add it, it will return this string. So we need to do something else here. What we need to do is we need to add a prefix F just outside of the code. So this is the string. This F goes outside of the code. If I save the script now execute again, write my name, and now we get the expected output. Note that we've got two variables with the same name here, and what it will happen is that first Python executes a script from top to bottom, so it executes the first line, it executes the second line, so it will store hello audit in the message variable. But then we are overwriting that variable. So in this case, the string will be written in that message variable. So wherever you create in here, whatever object you store in here in the variable, that object will be the current object that that variable will refer to. In this case here, we print out the object that you created in here, which happens to be hello audit. Which one should you use? Well, if you think that your project is going to be run with Python 3.6 or above, then use this nicer version. It's more readable. If you think your project, your Python files will be run with Python two or 3.1 or two or three, then you might want to opt in for this method. Because sometimes when you deploy your script in a server, for example, let's say you want to execute a script every day at a certain hour, you want to deploy it on a web server, and that web server will have a specific version of Python. Sometimes that version is Python two. So in that case, you want to adjust your scripts so that it works with Python two and the web server, the server, the computer will run your script with a particular Python version. We're going to look at this later when we deploy the web apps. So for now, these are the two methods of string formatting. 42. String Formatting with Multiple Variables +: Previously, I introduced you how to dynamically insert the value of variable inside a string. So here we constructed hello and whatever value the user entered in the input function. So this worked with Python two and three. This works with Python 3.6 and later versions. Now, what if we want to insert more than one value inside the string, how to do that? For example, let's say, the first input function will ask us for the name and the second will ask us for the surname. Let's call this variable name and this one surname. To use this version of string formatting with two variables, you need to do this. Instead of just one variable, you need to use round brackets and then enter all the variables you want to insert in the string name and surname in this case. Now, if you execute this, you're going to get an error. So you need to do something more there. Let's say audit. Ulce and you got a type error. Not all arguments converted during string formatting, which means that the arguments are name and surname. Not all of them were converted because only name was converted because you only had one placeholder here, percentages. You want to have two placeholders, one for surname, two. If you execute that, Well, we get another error, but that's not related to this line here. This line is perfectly fine. It works. Why does it work? Well, because you can see that the error happened. So this is where the trace back starts. You see that the error happens in filebsics dot i, which is the file where we have the code in line five, which means that above line five, everything is okay. So this line now has passed the error checking. It's free of error. So this is the line that has the error, and it's a name error, name user input is not defined. So this user input here has not been defined in our code. We don't have a variable with that name. We're just using it here, but we didn't define it. And here is a trick. If you don't want to execute that line, you can command it out. So by adding this symbol here, Python will ignore this line. It will treat it as a comment. Not as code. So save the script, execute. Enter your input as user, and this is the output we get this time. So that was a good exercise on how to fix errors. Now, back to our string formatting operations. Let's see how this now will work with two variables. So user input is not a variable anymore. We want to use name. So hello name, and then we want to have a space here. So this is a white space. So name, white space, surname. And it's as easy as that. Execute. And you get the output hello or the suche. So that's the message variable, the string of the message variable. So in this way, you can put as many variables as you like. For example, what's up? When when could be a variable. Today, the string today is part of the wind variable, the win variable will be replaced in here by the value that it currently has, which is today, execute that. And that's how it works. And that's what you need to know about string formatting in Python. 43. Introduction to For Loops +: Hi, welcome back in this new section. In case there are gaps on your Python knowledge so far regarding the Python basics that you have learned throughout these sections, then in this section, I'm trying to fill in those gaps so that you know what's going on. So we'll do that by putting all the pieces together by creating one bigger app with the blocks of code that you learned so that everything will start to make more sense and you know how to make real world programs. So this is the first step towards making real world programs. And this is not really real world program because we will make some more real world examples in the next sections. So this is just to make sure that you learned the core Python concepts well. So let's start with the next video. I'll see you there. 44. How and Why to Use For Loops: In this lecture, I'll explain one of the most important concepts in Python programming, and that is four loops. I'll use an example, so you not only understand the syntax, how to write a four loop, but you'll also understand why you should use four loops. Let's say we've got these temperatures for Monday. Maybe this was recorded in the morning in midday and that in the evening. How can we make a program that prints out the rounded values of each of these values? Like that. So that would be the expected output. You can see down here as you get nine because 9.1 round it up to a whole number would be nine, and then 8.89 again and 7.68. How can we do that? So we need to find a way to access the items of the list. And you know a method already how to access list items, which is using indexes. So if you want the first one, you use zero. So you want to print out the first item, that, however, would print out 9.1. You want the round version of 9.1, which is maybe you want to look to have a look at what functions you have available. Like that. So have a quick look here and you'll be able to find a round surround, which means you want to round a number, surround 9.1, you get nine. And in our case, the number we'd like to round up is this expression. So we want to apply around here and in parenthesis put that expression, so that's number 9.1. So give it a try before writing the entire code, and that's fine. Do that again. But with one and with two. Execute, and you get the expected output. Okay, that's fine. It works. But what if you had a big list of 100 items, you'd end up with 100 lines of code. Well, I can show you how to do that with just two lines of code instead. This is how you do it. You use a four loop for temperature, choose a name for a variable. For temperature, you see how these keywords are highlighted. So these are actually Python reserved words. Temperature is just a variable. That's why it's in black. In Monday temperatures, use a column, and what happens after a column I told you in the earlier video? Well, indentation, which happens automatically in visual studio code for spaces. What do we want to do for each of the temperatures? Well, we want to print out the round form of temperature. Just like that, save, execute, and this is the output. So in just two lines of code, we are able to execute some commands for all the items of an array, which is a list in this case, but it can also be a string. For example, for letter in hello print letter. And hello is printed out there. And of course, you can do whatever you like there. Title, get the first item, which is a letter. So the letter will be capitalized like that. So let me go one more time through these two lines to explain them what they mean. So what the loop does is for temperature in Monte temperatures, so you are creating a variable, and what the loop does is it goes through all these items one by one with loops. So in the first iteration, temperature will be equal, so the variable will be equal to 9.1. Therefore, the round function will round up 9.1 and print it out here. And if there are more lines in here, for example, print, done. If you do that, you see, if there is another more line, like after nine, this line is executed, so you get the string done printed out. If there are more lines, those line will be executed. If there's no more lines, then the execution goes again on the top of the four loop, and the loop gets the second item this time. So temperature this time will be equal to 8.8. And the same thing happens again, round it up, print it out. D is also printed out, goes to the next line, 7.6, and so on. And then after 7.6, the loop tries to see if there are more items in this array. If there are no more items, what happens is that this indented block, the execution of this block finishes and Python goes to the next lines to execute what's left in the script. 45. How to loop Through a Dictionary +: You saw that looping through a list is straightforward. You just do it like that. However, if you have a dictionary, it is a bit more complex. Again, you do four, pick a variable name in the dictionary, you want to iterate, but here you want to specify what you want to iterate. Do you want to iterate over items, keys or values? So if you want to iterate over items, you'd apply that items there. Don't forget the column and print. Great. See what happens. So you get these items printed out as a tuple. These are tuples. So the key and the value for each iteration. If you wanted the keys instead, you just write keys there and if you wanted the values, you just write that values and you get the values. That's how you iterate over dictionaries. 46. How and Why to Use While Loops: So you learn that a four loop iterates through a container, which could be a list or a string or a tuple, and the loop will terminate when the container is exhausted. So, for example, it prints out one, two, and three. And when there are no more items, the loop ends. So a four loop runs until a container is exhausted, and a whileloop a wire loop runs as long as this condition is true, let me execute that and see what is going to happen. So you will see that 11 is being printed out all the time. So if I scroll up here, I'll not be able to find where the starting point was because there's 1 million ones now being printed out there every split of a second. So what's going on here is that a Y loop Y is a keyword, and then that is followed by a condition. In this case, the condition is that A is greater than zero, which is true. So A is actually three, that means this condition is true. And as long as this condition is true, this will be printed out. So under the Wile loop, you can have as many actions operations as you want. For example, let me interrupt this with Control C on your terminal, and then add another line here, print two, save, execute. So one, two, one, two, one, 21, two is being printed out. Okay, I'll interrupt that. Now, the rate that these numbers are being printed out depends on your computer processor speed. So the faster your processor, the faster you'll get the actions here, these operations being executed. Now, of course, this will always forever be true because it's just a static declaration of a variable here, so no one is changing it here. Therefore, the condition will always be true. You can see in site Python when you check something three is greater than zero, you get true. So this is basically wild true and you'll sometimes see it like that. So just delete the first line. Exit here, execute the code again. So again, the same thing happens because true is always true. However, this is not how wild loops are used in real world. It's meaningless to check if true is true and print out something all the time. So let me go ahead and explain wil loops in a better example in the next video. 47. While Loops with User Input: So we had a script that checks if a is greater than three and prints out these operations if that is true. Now let me go ahead and use a more real world example. Let's create a variable here called username and give it a value of an empty string. And here, let's check if username is different than the real username, which let's suppose it's Pi Pi. Now, while that is true, we want to ask the user to enter an username. So let's see what's going to happen. Enter user name, we got the prompt here by the input function. Pi. No, we get Enter user name again. Pi Pi, maybe. No. Pi Pi. And so this time we don't get a prompt anymore. The execution of the program, so let me explain what happened here. We declared the empty string to variable username. And then here we check if the value of the username variable is different than Pi Pi. In this case, it's different because this is an enter string, and this is Pi Pi. Therefore, the first iteration will occur, which is this one here. So in the first iteration, we are asking the user to enter some inputs. This is what happened here in the first iteration. So enter username was prompted, and we entered Pi. Pi now is a string that will be assigned to username. And the loop goes through the second iteration. So while username is different than Pi Pi, which is true in this case, because username for now, it's Pi, the string Pi. So Pi is different than Pipi. Therefore, go ahead and execute the body of the wire loop again. Which is this one here. So ask one more time for the username from the user. So user name, the user enters Pi P this time. The loop goes through the head through the beginning again, and it checks if Pi P is different than Pipi. That's true, get the username again. In this case, we got Pi Pi. So user name is Pipi now. The loop goes again while username is different than Pi Pi, in this case, that is not true because in this case, the username is equal to Pi Pi. So Pi Pi. Is it different than Pi Pi? No, that's false. So in the third iteration, this will be equal to false, and that is when the loop ends. So four loops end when the container is exhausted and one loops end when the condition is false. 48. While Loops, Break and Continue +: In the previous video, we build this code. The code goes like this. We assign the empty string to username variable. Then we build a wire loop which checks if this condition is true. If the condition that username is different from Pi Pi, if username is different from Pi Pi, this is going to be executed. In the first iteration, username is actually different from Pipi because username is an empty string. Therefore, this is going to be executed. The program asks for the username. If the input is A, for example, A will be assigned to user name and then the second iteration starts, so while A is different from Pi Pi, which is true. This is going to be executed again. That's why we get this prompt here again. If you enter Pi Pi, the loop ends because in the third iteration, Pipi is not different from Pipi so this will not occur anymore. Now there is a different way to do this using a break statement instead of doing the above, let me do it another way, again, using the Wile loop. But this time, you want to check if true, while true, which is always true, so the loop will always execute until we break it. So while true, you want to ask for the username. Input, Enter username. Now, we want to create a conditional here to check inside the Wile loop. I username is Pip Pi, break the loop, else, Continue. Let's see what this will give us. Python three, B that Pi. That's the right side script. Enter user name. Hm, no, no. Pippi? Yes. Let me try again. If you enter Pi Pi right away, again, the loop terminates. I do prefer this actually because it gives you more control of the workflow. So this is what happens here. While true, which is always true. So the first iteration occurs because true is true, and we ask for the username in the first iteration. So in the first iteration here, the username was ASFD. So if ASFD is equal to Pipe Pi, break the loop. That is not the case because ASFD is different than pipi. Therefore, this will not occur because this condition is false. Else will be executed. Continue. Now, what continue does is it moves the control on top of the loop again. That's how you use break and continue in while loop. Both ways are correct, but I do find this more readable. 49. Building a Program in Python: Hi, welcome back in this new section. In case there are gaps on your Python knowledge so far regarding the Python basics that you have learned throughout these sections, then in this section, I'm trying to fill in those gaps so that you know what's going on. So we'll do that by putting all the pieces together by creating one bigger app with the blocks of code that you learned so that everything will start to make more sense and you know how to make real world programs. So this is the first step towards making real world programs. And this is not really real world program because we will make some more real world examples in the next sections. So this is just to make sure that you learned the core Python concepts well. So let's start with the next video. I'll see you there. 50. Problem Statement in Python: Hi, it's Arditi your instructor. If you follow the previous videos of the course, that means you learn the fundamentals of Python, and that was variables, data types, functions, conditionals, loops, and user input. That is the core of Python. Whatever application you will build, be it a data science script or a web app or something that automates your daily tasks, you're almost always going to need all those fundamentals. Before going further to more advanced features of Python in this section, let's take some time and meditate on what we learned. By meditation, what I mean is to think a little of these fundamentals that you learned. And the best way to do that is to create a program that uses all those core features of Python. Without wasting any more of your time, let me demonstrate the program that we're going to build. I've saved the code in a script. I'm not going to show you the code right away. I'm going to show you the output. So when I execute the code, I get a message printed out, say something. So it's a prompt that is asking for user input. Let's say it's a good weather today. Enter the program ask again for input. How is the weather? There there's only some clouds here. Enter and now if you want to end this program, you want to press backslash, press Enter, and this is the output. What this program is is it asks you for inputs. You enter the input again and again and as soon as you enter ends with a backslash, Backslash end, the program will terminate, and it will output the phrases you entered capitalize. So the first letter is capitalized, and a period is added to these kinds of sentences, and a question mark if that is a question like this one in here. And same for this with a period. And this is our secret string. So it's a backslash d. When the program gets that string, that means it's time to end the program and get the result. So this is not one of the ten real world applications that I promise to build in this course. The first application comes later in the course, but this is just to practice what you learned so far. So even though it's a useless program, obviously, who is going to need this, but it's going to help you a lot to know how to use the conditions and functions and loops. So please do this after this video ends, what I'd like you to do is to take some time and think how you can solve, how you can code this program. Now you know the output. Try to think and maybe try to write some code. Why not? I don't expect you to solve this actually. But still, if you put yourself into problem solving mode, and then when you see my solution in the following videos, because I'm going to take you through the code step by step, how to build this. Then you're going to have an aha moment. And that is when you memorize things better because in your mind, that was something you needed to know when you try to understand how you can do that. And then you see how it is done, and then you learn it better. So yeah, I'll talk to you in the next videos. 51. Approaching the Problem: Great. Let's go ahead and build this program now. So let's take another look at the output because when you build a program, you want to have a very clear view of what the output will look like, and then try to split the big task into smaller tasks. So for example, let's say, this program is asking for user inputs over and over again. And it's getting some strings in this row format, no period with a small letter in the beginning. And then if the user enters backslash d, the program knows that string and it returns the outputs. So what the program is doing is it's capitalizing these strings. So first letter is capitalized, and it's adding a period or question mark. Now, you see this is a list of phrases here of sentences. But as I told you try to split the task into smaller tasks. So try to split the output into smaller pieces of output. In this case, don't think about how to generate this list, but think about how to achieve the minimum viable output. In this case, that is how to get a row string such as this one here and how to convert it into this string. And the best way to do it is by using a function to define your own function that gets this string and produces this one in here. So first thing is to create a function. Let's do that in the next video. 52. Building the Maker Function: So let's start by creating a function that turns these kind of strings into this form. Define let's call this sentence maker. So it makes sentences out of row strings. Let's call the strings phrases. Phrase. So it gets a phrase and first, you want to capitalize that phrase, right? So maybe create a variable inside that function, call it capitalized or wherever you like, and say phrase and use the capitalized capitalized method of strings. And in the meantime, you can use your Python interactive shell to try out methods to see how they work while you at the same time, create a function in your editor. So, for example, let's say, I want to capitalize this string. First, I would like to try out how the capitalized method works. So now I'm sure that it capitalizes the first letter, so that's fine. No, we want to add to concatenate a period or a question mark to these phrases, right? But that depends. And so we are talking about a condition here. The program has to make a decision whether to put a period or a question mark at the end of the phrase. So let's go ahead and build the condition. If phrase. So how can we differentiate between questions and simple sentences that end with a period? Well, there may be different ways there, so that depends on the programmer and how sophisticated you want to do that. But let's keep it simple. And let's say that questions are all those that start with an interrogative words such as how, why, and what. And you can check that with let's say you have a sentence, like, how are you again? You can use the start with method, which gets a tuple as input. So a tuple and inside the toole, you can have some strings that you're checking if the sentence starts with any of these strings inside this tuple. So let's say how, what? And why. So that will return true because how are you starts with one of these strings. Another scenario, like, it's a good weather, you'll get false. So we can make use of that and say if phrase starts with How? What? And why? You can do that, or even better would be to get this tuple and save it in a very well. Let's say interrogatives and put it there. So then here you just put the variable, and that will make the code more readable. So if the phrase starts with interrogatives, what we want to do in that case is to construct a string. So let's say return the function will return this string. So that is capitalized. So capitalized will be the capitalized version of the phrase that the user enters, and then we want to add to that a question mark just like that. So that will be replaced by capitalized by that string, and that will add a question mark to that. So that will happen if the phrase starts with any of the interrogatives else return. In this case, we will return a sentence with a dot with a period. Again, capitalize is what we put here. Let me demonstrate so far what we have. Sentence maker. So we want to execute the function, right? With a word, with a phrase. How are you? Save, execute. And so we get the sentence correctly. How are you? That's it. Now we have a function that does something and does it good. Let's now think about the other aspects of a program in the next video. 53. Constructing the Loop: In the previous video, we build this function here, which gets a phrase as input, so a string, and if you execute the function, it will return that version of the string. Now, the output of the program that you are building in this section is going to ask for these phrases over and over again in the form of user input. So we are talking about getting user input from the user. And since that is happening, repeatedly, we have a hint here that we're talking about a loop. And since this loop, so when the user enters backslash ends, the loop ends with that string. That means we're talking about a conditional loop, and that makes us think about wile loops because wile loops work on a condition basis. So let's say the Wile loop will run all the time, so it will ask for user input. Input, say something, a column and make some space there just for decoration. So what happens if the user enters some input? Hm. Well, first, we want to check that input if that user input is actually the special string. If that is the case, we want to break the loop. Else. What we want to do? Otherwise? Hm. So you saw those sentences there. They looked like a list. So it was several of them. That means we're talking about having a bunch of items. And when you think about many items, you think about list. So maybe we want to store those phrases that the user enters in a list. How can we do that? Well, we can do that by starting with an empty list outside the loop. So Python will execute the function definition. This we don't need it anymore because we just used it when we tested the function. So once the function definition is read by Python, we are not calling the function here. We're going to create an empty list and then start the loop. The user will be prompted with a message. If a string that user enters is this, we're going to break everything. So the loop will end, else, if that string is not what user entered, else, we want to append the user string, so user input into the results list. So at the end of the loop, so unintended here, this is after the loop terminates, which happens only when the break happens. So when the user enters this, after the loop terminates, we're going to have a list with lots of data. So print results. How are you? Whether it is good and and and this is what we got. Okay, I know. These are the strings that the user entered. So how can we get the actual strings? Well, that is very easy. Here we are appending to the list the row strings that user entered. But we have a function that can convert those strings into sentences. Let's use that function. We're going to append the output of the function. To get the output, you need to call the function. To call the function, you need an input for the function. The input here is the user input. Just like that, execute again. And we got this output as we expected. So we are making good progress. However, we don't want a least output here. We just want a string output without those square brackets. So how can we actually merge or concatenate all these strings to make a single text as a string? Let's do that in the next video. 54. Making the Output User-Friendly: So to concalate all the strings into one single string, you can use the join method of strings. So this is a method of strings. This is a string here. For example, let me put this string. It's just a dash, but it's still string. This joint method gets a list as input. How are you? Good, good. So that is a list of strings. If you execute that, these items of the list are going to be joined by this string here that you declare in here. So if you add more to make it more clear, so you're going to get a dash joining all these strings, these items of the list, the first item, the second item, the third item. We can make use of that here by saying, join the results list. Save that execute. Weather is good and so how are you? Weather is good? We have a small problem here. We probably need a space between those strings. So we can do that very easily. You can just put a space in the string and then execute again. And that is the outputs that we were expecting for our program. So this is how you make this program in this section. You define a function on top of your script that does something and does it very good. Then you iterate, you make a loop. You ask the user for input in each iteration. Immediately check if the input was the string. You don't want to append first, and then check if the user input was equal to this. So you don't want to have this as the first condition because if you add that, that means if the user enters here, backslash end, and then after that, you had the results that append, that backslash end string will be appended to the results list. You don't want that. Therefore, you need to check immediately if the string is backslash d and break the program if that is the case, else, do this. So store the output of the sentence maker into the results list. Then finally, just concatenate the items of that list and print out the results, which is this one here. I hope this program was useful for you and you learned something how to put pieces together. In the next videos, we're going to learn some more advanced things about Python, and after that, we're going to go through the first real world application. A the next application after that and the next, and so you're going to have ten applications. And I know that if you take those applications seriously, you're going to be a good programmer. I wish you continue to enjoy my teachings in the next videos. 55. Introduction to List Comprehension: Hi, welcome back. In this section, you learn about list comprehensions. Now, list comprehensions are similar to four loops. The main difference is that in a list comprehension, you write the code in one single line. And with four loops, you have multiple lines. And also, list comprehensions are a special case of four loops. They are used when you want to construct a list. So a list comprehension is a loop that constructs a list. You can construct a list also with a four loop, but as I said, the list comprehensions are just one line. So that makes the code more elegant, more pythonic. So let's learn about list comprehensions in this section using examples, see. 56. A Simple List Comprehension: Throughout my experience with working with large datasets, I've noticed some techniques that data collecting institutes use to save storage and make them their data have less space on computer disks. A common technique is not to use decimals. For example, if you search for temperature data, you'll not see the actual temperatures that let's say these are Celsius, you'll not see them like that, but you'll see them without the dots because that will save storage in the servers. So one character less, that means some bytes less. So your duty as a programmer is to actually divide all those values by ten so that you get the actual data. So let's say these data were in some text files, and we open this data with Python, and the course actually covers how to manage how to open text files in Python. But let us skip that part for now. So let's say we got them loaded as a list here. Now we want to actually divide by ten, any of them. So how do you do that? Well, a technique is to iterate over TAMs. So for temp in temps, and in each iteration, you want to do Temp divided by ten. But where do we store this temp divided by ten? Well, we can store it in a new list. Let's say, new temps. That is an empty list for now. So the loop will iterate through this list and in each iteration, we're going to append this value to new TEMs. So append this value. That looks okay. And then print out new TEMs. Let me go ahead and execute that. So this is the desired output. Now, that is very correct, but there is a neater way to do this in just one line of Python code. And that is by using list comprehensions. It goes like this. You don't have to create an empty list because a list will be generated dynamically, you'd say, Temp divided by ten, four temp in temps. Print new temps to see what we get, execute, and you get exactly the same output. So that is a list comprehension. It's a way to build list without having to create a four loop, a standard four loop because we actually have an inline four loop in here. So what's going on here is that we have an iteration here and in each iteration, we're going to store this value in the list in the new TEMS list. So this is like saying store temp divided by ten, but Python will say, Okay, but what is TEM? It's a new variable. We don't we haven't defined it anywhere. And then we say, Well, for temp in TEMs, temp is a variable of TEMs. So that's how you create a list with these values for each of the values of TAMS. That is a list comprehension. 57. List Comprehension with an If Conditional: Now, if you have worked with observations such as weather observations, for example, temperatures, you might have noticed that you have these kinds of values sometimes in those data, which means there was no value, no valid value detected for that observation, and organizations use that special value to mean no data. So if we wanted to use a list comprehension where we divide by ten all these values, we want to be careful not to divide this value by ten. We want to ignore that. For that, we need an I conditional inside the list comprehension. We can do it like that. So create a new variable where you will store the new list. And again, let's say temp divided by ten for temp in temps. If temp is different, for example, the minus 9999. Print new TEMs, execute on the terminal, and we get the expected result. So this is just like the simple loop that we saw in the previous video with the addition of the I conditional. So that is conditional. We are checking if temp is different than minus 9999. 58. List Comprehension with a If-Else Conditional +: Previously, we built this list comprehension, which iterates over this list and divides by ten each item of that list, and it ignores only if temp is different than minus 9999. So what happens if temp is equal to that number? Well, the loop, the list comprehension will ignore that value as you saw in the output. So that was the output. So what if you want to put another value instead of that? Let's say you want to put zero instead of that negative number. In that case, if you think you can just do se here, zero, you try this out, you'd be wrong because that will produce a syntax error. When you have an Is inside the list comprehension, the order of the components is a bit different. You have to get the four temp in temps, so the loop has to be after the conditional, just like that. If you execute that, you're going to get the expected results. So you see the zero there instead of minus 9999. So the list comprehension this time goes like this. Give me temp divided by ten, only if temp is different than this number, else, give me zero for temp in temps. So always remember that if you have to do an Is inside the list comprehension, the for loop goes at the very end like that. 59. More About Functions: Welcome back to a new section. You learn more about functions throughout these videos. You did learn how to define a function and how to call it previously in the course. But here, you learn some more advanced concepts about functions, and you really, really need to learn about functions because they are some very fundamental blocks of code. So you write your programs by using functions which do certain things. So let's learn more about functions. See you in the next video. 60. Functions with Multiple Arguments: Maybe you remember the len function and the is instance function. The len function takes only one argument and the stance function you so it takes two arguments. You can also see that in the help documentation. Obj, that's the only argument that length takes. And if you look at stance, it will get obj and class or tuple. So some functions need one argument, some need two. Now, these two functions were built in Python functions. So the Python developers team designed these functions. So how can we make our own functions with multiple arguments? Pretty easy. Let's say we want an area function that calculates the area of a rectangle to have more than one argument, you just need to separate the parameters with a comma. So parameter and argument. A parameter is what we refer to these variables when we are defining the function, and when we call the function like here, we refer to them as arguments in the function call site, so to say. So return A times B that will return the area of a rectangle. And of course, when you call the function, you just pass values for those arguments. And you get the value output correctly. 61. Default & Non-default Parameters, Keyword & Non-keyword Arguments: In Python, arguments can be mainly of two kinds. We have non keyword arguments and we have keyword arguments. These two here are non keyword arguments. They don't have the keyword attached to them. However, if the case was this, Things would still work the same. But these two now would be called keyword arguments. Non keyword arguments, which is this one, two, are also referred to as positional arguments. They are called positional arguments because the way you communicate these two arguments to the function definition is based on position. So the first position, four goes for A and the second five goes for B. So positional and non keyword arguments is the same thing if it was keyword arguments. The position actually doesn't matter. So you can pass the value of B as a first argument if you like, and four will go to B and five will go to A. So as long as you pass them like that, keyword arguments, the position doesn't matter, you still would get the same output. Now, we also have default parameters, not arguments parameters. What that means is that a parameter might have a default value like that, which means you don't have to specify the value of that argument when you call the function. So we assign five to A and B is six by default. Therefore, we get 30. A doesn't necessarily have to be a Kord argument. It can also be a non Kurd argument here in the function call, you still get the same output. Of course, you can also assign different value to B. Just like that. And lastly, you can also leave it like that to non keyword arguments, and you still get the output correctly. Something you should know is that a default parameter cannot be before non default parameters. If you execute that, you'll get an error. It says non default argument follows default argument. So non default follows default argument, which is A. And that I think is some very good information about function arguments and parameters. 62. Functions with a Arbitrary Number of Non-keyword Arguments: Some functions in Python such as the len function, get only one argument. If you try to pass more than one, it will return an error saying that it takes exactly one argument. Some other functions such as instance, take exactly two arguments. Two, if you try to pass three arguments or just one, you get an error. Some other functions such as print take an indefinite number of arguments, and you saw how we can define such functions with only one or more argument, but I haven't still explained how to create these kinds of functions. Let's create one. Define, let's call this mean to calculate the mean of a series of numbers. So imagine this was our function. We want to pass as many items as we want. We actually did create a mean function earlier, which we could call like that, but it still got only one argument, so it was a list like that. It's still one object, one argument. In this case, we don't want to pass a list. We want to pass as many items as we want. So Min and then what you do, you use asterisk then arcs. This can be anything actually after the asterisk. Any variable name would work, but it's a good practice because every programmer uses arcs. So it's good that you use arcs so others can read your code. And you also get used to reading others code by using arcs all the time. You know what the others are talking about. Now, let me show you something before I apply the algorithm that calculates the mean. Return arcs. Let's see what we get here. Now let me call the function. So one, three, you can also pass strings, whatever you like, like that. And what you get is actually a top pole containing all the items, all the objects that you passed in the function coal. So that actually is a top pole. So what can we do with a tuple where we can calculate the sum of arcs. So arcs is a variable, not asterisk arcs, divided by the length of arcs. In this case, it would get an error because we have A there. So remove A from there and try again. A is a string, so it doesn't make sense to have the average of a string. So we just created a function with an arbitrary number of known keyword arguments only. I say only because you cannot have keyword arguments here. You see X equal to three would not work here. If you want keyword arguments, then see the next video. 63. Functions with a Arbitrary Number of Keyword Arguments +: So this function here that we built in the previous lecture accepted an arbitrary number of non keyword arguments. For keyword arguments, you have to add another asterisk to asterisk and then pass a variable name, but Kew arcs is a convention. So please use that even though you don't have to and then see what KeyWRc is, which stands for keyword args. If you try to call the function there, we'll get an error because this is about a function with an arbitrary number of keyword arguments only. Therefore, all these arguments have to be named arguments, keyword arguments, having the keyword, the argument name. B and C like that and execute and you get a dictionary. The dictionary will have items where each key will be the name of the arguments that you used when you called the function, and the value will be the value of that argument. Functions with an arbitrary number of keyword arguments are more readily used than functions with an arbitrary number of non keyword arguments, such as the print function that I told you earlier, where you can just pass as many arguments without a keyword. So there you have it. 64. Introduction to File Processing: You have learned about different datatypes that you can use in Python. For example, you learned that you can have strings and you can have lists and numbers and so on. And we stored these data types in variable. So a variable was associated to a string, for example. The problem with this is that you are storing data inside your Python program. If you want to really, really store dot time, for example, you want to store weather forecasts, you don't want to write those forecast values in strings or in numbers in your dot PY script. What you want to do instead is you want to have those data in external files, for example, text files or CRC files, or later on, you learn about databases, how to store data in databases and get those data via Python and process them in Python. But in this section, you learn about how to store data in text files and how to get data from text files, how to create text files with Python, how to read the data from text files and process them with Python. So that is a very, very crucial concept of programming. And so that's an advanced concept, and you learn that in this section. So have fun, and I'll see you in the next video. 65. Processing Files With Python: Here on my desktop, I have a text file, flout dot TXT. If I double click it, it will open with one of the text editors that I have installed in my computer. The text editor is a program, and in this program, I can read this file, so I can read these lines. I can write more lines here, I can copy this and paste, multiply them to have a lot of these lines in here in this text file, and I can do all this with this text editor program that I happen to have here in my computer. Now we can do the same using Python, which means we can read the file with Python, we can write more content in that file. We can multiply this and we can actually do that very efficiently. If I had to multiply this, I had to copy and paste them 1,000 times maybe. But with Python, you can do that very easily. Let's go ahead and do the same thing with Python and let's start with reading the file. So how to read a file with Python. I'll show you that in the next video. 66. Reading Text from a File +: So this is how you open a text file with your favorite text editor program, and let me show you how to do the same with Python. Of course, experience is a bit different. It's not about double clicking the file, it's about writing code. So when you open that file with your text editor, what happens is that some object is created in your temporary memory of your computer in RAM. So the file was on the hard disk. When you open it, it's created as some type of object in the RAM. Same thing happens with Python. In this case, you might want to store that object, that file object that you're going to create in Python. You might want to store it in a variable. Let's call it my file. The open function is what creates file objects. And since it is a function, it will get an argument. Now, this basics dot py file is in the same directory with the fruit dot TXT file. Please download the fruits dot TXT file, which looks like this. Let me split it here. You can drag a file on the side here to have two windows on Visual Studio code editor, but you can do that even in other editors, I'm sure, if you're using other editors. This file for now, let it be in the same folder with Basics dot py. Once you do that, then the input for this function is the path to the file. In this case, that would be fruit dot TXT, since the fruits DTX file is in the same directory with Basics dot pi. No, to read the contents of fruits DL TXT in your text editor like we did graphically, it just about double clicking the file, and then you see the content on the text editor interface. In Python, things are a bit more they have to be a bit more explicit. You have to specify what you want to do because this file, we have just created a file object. If we execute that, nothing is going to happen. An object is going to be created in temporary memory and when the execution of the program ends, the object will be deleted from the memory. Just like when you open the text file with the text editor and then you close it, object, the file object is deleted from the temporary memory. If you want to read, what you might want to do is print out my file. Now, my file has a read method. This is the file object, which has a read method. It doesn't take any arguments, so just leave it like that, save, execute, and here you get the output of the file. This is how you read a file in Python. 67. File Cursor: Now, something you should know is the cursor concept. What happens here is that you create a file, a file object is created, and then when you apply the read methods, before applying the read method, the cursor stands at the very first character of the text file. When you apply the read method, the cursor goes to the end of the text file. So now after the read method has been applied, the cursor stands here. If you apply another read operation like that, save, execute. What's going to happen is that maybe you were expecting these lines to be printed out two times. What happens instead is they are printed one time, and then this is just an empty string because the cursor after the first execution of read was at this point and below this point, there's nothing, so you get that empty string there. What you can do is if you want to print the content many times, what you can do is save the content in a variable and then print the content as many times as you wish and you'll get the output two times as you can see here. That's because the read method was executed only once here. That's something you should know. 68. Closing a File: When you create a file object, a file object is created in RAM and it's going to remain there until the execution of your program. Therefore, it might be a good idea to actually close the file so that the file is deleted from the memory once you are done processing that file. For example, in this script, you are creating the file object, and here you are reading the content of that file object and storing it as a string. So my file Read output a string, which represents the text of the file. That string will be stored in this content variable. So here I'm done with processing the file, then I can after that, I'm just processing the string that I saved in this variable. Therefore, it makes sense to apply my file dot close. Even though this is not strictly mandatory, but it's a good idea to use it. So if you do that, you'll still get the correct output. Something you should know now is that if you apply my file that read again after you have closed the file, you're going to get an error. It says that this operation is being performed on a closed file, so you cannot do that. So this is how to create a file and close it, but there is a better way to do all that. I'll show you that in the next video. 69. Opening Files using with: A better way to do this to create the file, read the content, and close the file is to use the With contacts manager. The way you do that is, again, you use the open function, which works the same fruits TXT. Now, you say a myfile. My file is just a variable, and then you have to indent. So what you have done here is you have created this myfile equal to open fruits dot TXT, exactly the same. Difference here is that you'll write everything that has to do with processing that file object. You'll have to write everything under this line indented under that line as a block. That will make things more organized. So in this case, what we want to do to the file is to read it like that. Once you are done, then you just close the indentation. So the next lines will be unindented like the print line. See what's going to happen here. That is the expected output of the print content. Even if you delete this, not to confuse you, again, you get the same output. So this output is actually of this line. And closing the file is not necessary here because the With context manager will apply the close method implicitly. So your file will be closed once this block ends. So please use the With contact manager, and this is how you do it. 70. Using Different Filepaths: So far, our basics PY and our fruits dot TXT file were in the same directory, in the same folder that allowed us to only write the name of the file in the basics PY file. However, if the fruits that TXT file was, for example, inside this other directory, so I just moved fruits TXT inside files. Fils is a folder that is in the same directory with Basics dot PY. So Basics that's PY in the same folder with scripts with files, and fruits inside files. In that case, if you execute the basics PY file, you're going to get a file not found error. No such file or directory, fruits dot TXT. And that is true. There's no fruits DTXT in the folder where basics Dt PY is so. What you need to do is you need to specify the complete path to the file relative to the basics dot PY that is files slash fruits dot TXT. Execute that and things will work. 71. Writing Text in a File: Let's take a look at the help documentation of open. And you'll see that the open function gets a bunch of arguments. The first two are the most important ones. We already used file, which is the path to the file object. And for these other ones, we use their default values, which means for modes, we used R, R means read. Therefore, this code here is the same as this. So you get the same output. Which ones should you use? Well, to make the code simpler and shorter, this is fine. To make the code more explicit in terms of fadability so that others can see that this is about reading the code, then you'd use this. Either way is fine. Now, what can you use for writing? For writing, you'd use W for write. And let me create a new file under the files folder. Call it vegetables. So a vegetables file doesn't exist currently in my files folder. It will be created by the open function. And then in that empty file, we're going to write something we Tomato. Of course, the content variable doesn't make sense here because we are not fetching some data from the file. We're just writing there. So let's keep it like that, save it. Execute and a vegetables, the TXT file has been created in my computer with a tomato string there. Let me put it here. So the read method looks for an existing file. The right method creates a new file, and I should warn you that if the file exists, like in this case, fruit that Tix is there. If that is the case, Python will override the existing file. So if you open fruits DTIxti now, you'll see that you have this new content of the file. So the existing content is discarded. How can we write more lines? Well, you have to use the backslash N special string, which creates break lines. Onion, execute. So this is fruits TXT. And you get these three lines as we expected. Something you should know is that you can apply more than one method to the open file. Let's write garlic here. Now, intentionally, I didn't do something I was supposed to do to show you what happens. So Gaelic was immediately put after onion because there was no space or a backslash N operator there. If I put a space here, you, of course, would get a space between onion and Gaelic. But what you want instead is you want that after each line you write, you want a backslash N. And in that case, you'd get the correct output. So now you are probably wondering, well, I have this fruit that Tixifle. I don't want to overwrite it. How can I actually add another line under these existing lines? I'll show you how to do that in the next video. 72. Appending Tex to an Existing File +: Okay, so I have these fruits that CX file in here, which has these four lines which are not fruits anyway, but you get the idea. It's text. We want to add two more lines to these existing fruits that CX file. We don't know what is there at the moment. If you look at the open documentation and scroll down, you'll see here that you can pass different modes in this argument here. So, which we use already, we use W, and then you have X. If you use X, and try to write let's say Okra. If you execute that, it's going to say that file exists. So unlike the W mode, which overwrites a file, X will not override the file if the file exists. However, it cannot append content to an existing file because it says that the file exists. Therefore, we jump to the next mode, which is A. You see that Okra was added there, of course, with a small issue because there was not a brick line here in the existing text file. That's some information you should know, and if you know there is no brick line, then you'd need to let me say this text file, then you'd need to add a break line there to get the correct output. Anytime you add a new line, you'd need to add a brick line in front. Now, how about reading that content? Maybe save it in a variable and print out the content. Will it work? I don't think so. It says that the operation is not supported. The file is not readable. It's A, which is for appending. If you want to write and read at the same time, you want to add a plus. Just like that. Execute. You get an empty output. Why? Because of the cursor. So what's happened is that when we added the Oca line there, so at first, you created the file here at this point, the cursor is here, ok? Then you write the file. In this line, the cursor goes to the end of the file. So when you read now, you read whatever is left under the last line, which is nothing. What you can do is my file, Sk, apply a Sk method to put the cursor at the zero position once again. In that case, the cursor will go to the end. It will go again the zero position with this line, and then you'll read everything from there and down so you get the correct output. 73. Builtin Modules in Python: If you follow the previous sections of the course, then you have come a long way. So you now know the fundamentals of Python. You know how to solve fundamental problems. For example, let's say you wanted the number of characters of the string. So you have methods and you have functions that you can use. So for methods, you can search with deer SDR, you'd see the bunch of methods here that could be applied to strings, and then you can see functions built in functions. For example, the n methods would be handy here. It would return the number of characters for the Pi Pi Pi string, which is six. Now, all these here. So these functions and the string methods, they are all built in. So these are methods and functions that are written inside the Python software that you download and install from python.org. That software is written in C language. Therefore, these methods and functions are also written in C language. And as you see, these names here are available immediately in your Python interpreter. That means they are built in. They are inside that interpreter, and you can just call them without importing them. Now, what if we had some other problems like, let's say, you see the script here. What this script is doing is it's a loop. It's a while loop. So while true, which means it will run forever. So what it does is it's reading this file, vegetable dot TXT in the files directory, which happens to be in the same directory with basics dot pi. So that is the path of the file. And this text file contains a string. And so I'm reading it under this variable, and I'm printing out the contents in here. So if I execute this file, you're going to get the content printed out every split of a second and which depends on your processor speed on your computer processor speed. Now, what if we don't want this to happen every split of a second? What if you want to read the content every 10 seconds? Let me interrupt this with Control C. You'd soon realize that you don't have any built in function that does that that implements some sort of sleep methods in your script. So there's no function that you can use right away. In that case, you may want to look for built in modules. To do that, please use this syntax. Import CS, which stands for system and then CS built in module names. And here you'll get a list of modules, built in modules, so modules that are built in again in the Python software. So let's use one of them time. The way you use it is by importing the module name. Then again, you can use DR to see what you have for that module. For example, here you'll see we have a sleep method. Use help to see how to use that particular method. So it says that it gets the second as argument. So let's try it. T that's sleep. Let's say three, one, two, three, and so what time that sleep does it slips the script execution for a particular amount of seconds, three, in this case. That means we can implement that in the script. It's a good practice to import modules in the first line of the script. And then use that module in your script wherever you need it. In this case, what we want to do is, let's suppose this vegetable that's TX file is being generated on our server every 10 seconds. So let's say a software in the server is getting this data from somewhere, and it's writing a new content every 10 seconds. For example, now it's tomato, later it's going to be garlic 10 seconds. After that, it would be onion and so on. So we're getting new content every 10 seconds. So we want to print out the contents of the file, and then have the execution slip for 10 seconds. Now I'm going to save the script, go to the command line, execute it. So you get tomato right away. Now if I change this to onion, let's say the software changed it and save, click Save. Onion was printed out there after 10 seconds. If I change it to garlic, save. Wait, wait a few seconds. Garlic is printed out there. So every 10 seconds, the script is fetching the data from vegetables that CXC and printing it out on a command line. So Control C to interrupt it. This is how you use a module. Now, not everything is built in in your Python interpreter software. Some things, actually, many of them come in a different form that I'm going to explain in the next lecture. 74. Standard Python Modules: Previously you learned that you could get a list of Python built in modules using C built in module names. As an example, we use the time module, which would freeze script execution for a particular amount of seconds. Now, let me show you something. I'll execute a script onion will be printed out because it's there in the vegetables that CXT file. However, if I now delete this file, you'll see that the next time the script checks for the files, vegetables dot TXT path. So that's a file path. It's going to generate an error file not found error, no such file or directory. So imagine you had this program running on a server 247 and for some reason, the software that was generating these files, at some point, it doesn't generate the file, so your script execution will end and maybe in a minute, your software will start to generate the files again, but your Python script will not resume because it got an error here. So what we want to do we want to keep executing the Python script even when the file is not in the directory there. To do that, we want to make use of the OS module. Import OS, and you're going to notice that OS is not among the built in Python modules. Indeed, OS is a module written in Python. All these modules are built in, which means they are written in C language inside the Python software implementation. OS is not one of them. To find out where OS is staying, you can use OSs prefix. You're going to get a directory path there, which could be different depending on what operating system you are using. So please navigate to that directory. I prefer to go there directory by copying it without the codes. So copy everything without the des, like that. Go to your command line terminal, and if you are on Windows, use start and paste the directory there, and then press Enter. If you are on Mac or Linux, use Open instead of Start and paste the directory again. Press Enter, that will open your Windows Explorer or finder, whatever you have to open folders. So that the 3.7 folder that you see in here and then go to Lib double click. Then find the folder, Python 3.7 or whatever version you have. So Python three point something. Double click it. And here you'll see a number of Python files dot pi. These are all Python files. These are all standard Python modules, and OS is among them go to Oh here, double click it or open it with whatever you use as a text editor, and you'll see that this is actually Python code. Make sure to close it before changing it. So don't change don't modify Python standard modules. So I'm going to close it and you can use DR actually to see what you have available for that module. Among them, for example, I'm going to use the path object. So with as that path, and Path has a method called exists. The exist method gets an argument which should be a string, and it's supposed to be the path of the file you want to check if it exists in the current directory. So let's write the directory path to the file, and I get false because the file was not in the current directory. If I go there and create that file inside the files folder, so now I have a files slash vegetables dot TXT file path. If I execute that again, I'm going to get true. And we can make use of that fact in our Python program. So what we want to do is before opening the file in real mode, we want to check if the file exists because if we don't do that and the file is not there, this line here is going to generate that file not found error. So before doing that, we want to check if Os that path that exists. Files slash vegetables dot TXT. And since this is a conditional, we want to use a column there. And after that, whatever you want to do, it has to be indented. So with, it's going to be under if this is also part of the W block, so indent that as well. And then s goes inside the wire loop again. What you want to do under ls, well, maybe we want to print out File does not exist. And then be careful here. Time slip has to be outside of the IL block because you want to execute it independently of the conditional block, which means if the file exists, this is going to be executed. If the file does not exist, this is going to be executed. And after either of these is executed, always, we're going to execute time that slip. So let me save the script and execute it. And we got an error, OS is not defined. I'm glad this showed up because Modules have to be imported. Otherwise, you're going to get that name error because OS, before being used in here, it was not imported, and it's not a built in function or method such as print which you don't need to import. So its name is not available immediately in the name space. Save the script again, execute, and we get an empty string because vegetables is currently empty. Now, if I go and delete vegetables like that, wait a while. And we get this printed out. If you create the file again, write something there, save the file. Don't forget, pretending that the software is generating this file. So you get Gallic there. Now I can interrupt the script execution with Control C, and that are both standard Python modules, and they are exactly the same, so you can use JR with them. So all the Python rules apply to these modules. The only difference is that time is written in C language and it's built in inside the Python software, and OS comes as a dot pi script, and it came here when you installed Python. So it was basically copied in one of your computer directories, and you can import those all those modules, standard modules in Python. Now, of course, not everything comes with your Python installation. So things you have to install. So I'll show you that in the next video. 75. Third-Party Modules : In the previous lectures, we built a program that goes through the vegetables that TXI file every 10 seconds and it prints out its content. So the programs running here. Now, vegetables dot TXT is just a simple text file with some useless data like garlic and onion. What happens if we had some more real world data such as the Temps underscored the CSV file. So this is a CSV file, which is basically a text file. And it has a structure of multi columns. So every column has some data. You see here this is a header. It has two columns, SD one for station one and SD two for station two. So we have two weather observation stations, and they recorded this data, these temperatures. Let's say, these are observations in one day. This is in the morning and this is later in the afternoon and in the night. So we have two columns. Our duty now is to read this file every 10 seconds, just like we are doing with vegetables that TXT file. But instead of printing out its content, we have to print out the average value of all these values. So we should do that every 10 seconds. Well, normally, you'd have to do this every 24 hours because it makes more sense. Since these data are daily data, daily temperature data, they are being changed every day. It does make sense to print out the value, the average value every 24 hours. And of course, you can do that easily just change the value from 10 seconds to whatever seconds is equal to 24 hours. You can easily calculate that. But for simplicity here, let's just use 10 seconds. Now, while we can do this by using the open method to load the data in Python, that would load the data as a string. So this entire text would be loaded as a string in Python. Then we would have to apply some string processing operations to split all these values and convert them to float. But that would be like reinventing the wheel. What I'm trying to say is that someone else wrote some Python code that does this very easily in just one or two lines of code. And the guys who wrote this, they have built this as a third party library. So just like we used time and OS by importing them inside Python, we can also use another library for this case to load this data in a nice format in Python. Let me show you how. The library name I know is Pandas, and Pandas doesn't come by default with Python. So when you install Python, Pandas will not be there, but you can install it with PIP. PIP is another library that comes installed by default in Python, and it's used to install other third party libraries. A very important point I want to make is that the PIP command may vary between different operating systems and different installations of Python. For example, if you are using Python version 3.8, you might have to type in PIP 3.8 instead of just PIP. If you are using Python 3.9, you'll have to type in PIP 3.9. If you are using Python 3.10, which is newer than 3.9, you have to type in PIP 3.10. So to sum it up, you have to use your own commands. Whenever I type in PIP three, you have to use your own PIP 3.8 or PIP 3.9, et cetera, in your computer. So I'm going to use Pip three and then do install pandas. Note that you shouldn't change the install pandas part of the command. You should only change the PIP part as I explained to you. Okay, so Pandas is the name of the library we want to install. So the bars are filling in. That means the Pandas library is being installed successfully installed. Great. Now, let's go ahead and use Pandas in our script here. Import pandas, just like we did with other libraries. So these two, this was a standard library. It's built in inside the Python interpreter. And this is, again, it's a standard library, but it's not built in, it's written in Python. This pandas, this is written in Python as well, and now it was just installed in our Python installation files. Let me show you where that pandas is. Let's open a Python session. So if you import SIS and then sys dot prefix that will give you this directory. Whatever directory you have, copy it without the codes, and then you start on Windows and pay the directory on Mac and Linux open and pays the directory, press Enter, that will open the directory, go to Lib to Python. And then OS, for example, was here, Os dot pi. These were standard libraries. Now, whatever you install with PIP, it's going to be inside the site packages directory, which is down here somewhere, yes. So pandas, this is pandas. We just installed pandas. In this case, this is not a module, but it's a bunch of modules. And this is called a package. When you have several modules, that is called a package. But you can still refer to it as a library. So a library is a name used usually to refer both to modules and libraries. So code when you use Pandas, it doesn't make any difference. If it's a module or it's a bunch of modules, so a package. So the code of Pandas is all there, and we can use this code now in our script. So let me show you in the next lecture how we use this Pandas third party library. 76. An Example onThird-Party Modules: So let's go ahead and read the content of this file with Pandas. A very powerful data analysis library. We are going to dive deep into Pandas later on. We have a section dedicated to Pandas and we have applications where we're going to use Pandas a lot. But for now, let me just give you a quick demo how pandas works. Make sure you import it. I've inported in here, and then while through, let's keep this conditional to check if the file is there. In this case, that would be Temps today dot C SV. And then if the file exists, we want to load the data in this data variable. The way we do that is by using the read CSV method of Pandas. And there goes, you guessed it the path of the file. Like that. So if the file exists, read the data and then print out data dot mean. So, this object has a mean method. Let me show you later what this object is. But for now, let's go ahead and execute this script. So we are getting the mean of each of the columns. That is a mean for station one, and that is a mean for station two. So it's working. Now, if you wanted the mean of only the ST one column, you'd just do that. So that will give you the mean of the ST one of the Station one column. And so on. So the idea here is that import pandas, and when you execute this, what's happening there is that an object called a data frame is being created. You can see that you have a structured view of these data. So this is a specific object type. Just like we have integers and we have floats, we also have these other types that you can find in libraries in these third party libraries, so everyone can create their own types. And this is about libraries, so built in libraries, standard libraries, written in Python and third party libraries, which are almost always written in Python. That's about libraries. 77. Intro to Using Python with CSV, JSON, and Excel Files: Hi, welcome to a new section, and this will be very exciting to teach for me and also very, very useful information for you to learn. So we'll be working with external CSV files, Excel files, JSON files. So these are external files where you can store data and you can access these files. You can manipulate them from your Python program. So your program can interact with these files, and this is what you're going to learn in this section. So get ready, and I'll talk to you in the next video. 78. The Pandas Library for + Data Analysis: Hey, welcome to this new section. And in this section, you will learn how to use Pandas, which is a very important Python library, and you really don't want to miss that. So what is Pandas? Well, Pandas is a library providing data structures and data analysis tools within Python. Or if the word tools confuses you, then you can say Pandas is a library providing data structures and data analysis code. So basically, Pandas allows you to load data from different sources into Python and then use Python code to analyze those data and produce results, which can be in the form of tables, text, and also visualization with the help of visualization libraries such as book, book, which is covered later in the course. So for now, we'll focus on data without visualizing them, and Panas is great for that. So practically, how do we use Pandas? Well, you learn how to open text files using Python built in file handling methods earlier in the course. Now, what we opened from textFils was just plain text. But what if you want to load text files with data constructed of rows and columns. Or things get a bit complicated. But here is where Pandas comes into play. So you can probably do that using built in Python methods that you have learned in the course. But to be more efficient and to be much more efficient, you need to have a high level library such as Pandas, which is able to recognize such data structures automatically. I use pandas for loading data from data mining activities such as web scrapping. So you scrap data from a website with Python and then store those data in those data frames. So you use pandas to provide data structures for you in Python. And I use pandas for loading data from Excel files, and also use panels for analyzing those data instead of using Excel. Excel can be good for analyzing a small table of data that fits in your computer screen. But for data larger than that, you really want to use code. You write Python code once, and then you use it with other data as well. And you don't want to do selections and dragging and many other cumbersome operations that you normally do in a graphical based program such as Excel. So code is the way to go if you want to be efficient with data, and Python is great for that with Pandas. You really want to get a good hang of panels, and you will learn that in this section and also practice it with real world applications that we'll be building as you progress through the course. Let's go ahead and dive into some code now in the next lectures. See you. 79. Getting Started with Pandas: Great. Again, Pandas is a library that provides data structures and data analysis tools in Python. So in this lecture, you'll see what I mean with data structures and data analysis. So you'll see the main Pandas object, which is a structure that contains the data. And you'll see that we get data from the structure and analyze them. So I'll open a simple command line, and for now we'll use IPython just great for data analysis and working with data. But even better is Jupiter notebook. Jupiter Notebook is like a Python Shell. It's actually a combination of a Python Shell and a Python editor. And it's a browser based tool where you can write Python code, and it's very efficient, so it really boosts your productivity. But for this lecture, I want to start with simple things, so one step at a time, and I'll introduce you to pandas using IPython only. Then in the next lecture, I'll show you how to set up a Jupiter notebook previously known as the IPython notebook. So you'll set up Jupiter, and I'll show you how to work with Jupiter. So for now, let's go ahead and use the plain IPython console. Import pandas. And, normally, the first thing you do is you want to import some data, let's say, from a CSV file or from textFile or even an Excel file or JSON or other formats, which we'll be covering later. But there are also other ways to create a pandas data structure. Now, the first thing you should know is this data structure that I'm talking about is called a data frame. So that's a special object that will hold the data. And you can create one. You can store a data frame in a variable, let's say DF one. Mm pandas data frame. So I'm creating a data frame manually, passing values manually via Python. Normally, you want to use other files, like I mentioned. So data frame now think of data frame as a table. So you may want to pass a list of lists where each list will be a row of that table. So let's pass some data two, four, six and ten, 20, 30. You execute that, that was successful because you didn't get an error. Do you have one, and here is the data frame. So 246 is the first row, ten, 20, 30 is the second row. These zero, one, two are the names of the columns, and these are referred as indexes. So 01 here are indexes for the rows, and these here are the column names. The beauty of panels is that you can also have your own column names if you like. So I'm going to call this expression again, and I want to pass here a parameter called columns that expects a list of names. Which has to have the same number of items with the number of columns that your data frame has. So if you pass list with three items, you want to pass three columns here as well. Let's say price something random, age and value. You execute that and let me expand this DF one, this time you see that you have your own column names there. Now, similarly, you can pass custom names for the indexes as well by passing index as parameter, and then you'd want to pass a list with two items because we have two rows only let's say first, second, DF one, and you have custom indexes. However, normally, you won't have to pass custom indexes. Data normally have defined number of columns, but the rows, you may have hundreds and thousands of rows or millions there. So you really don't want to mess up with index names. However, the feature is just that in special cases. So there's one way to create a panel data frame, and you also have other ways as well. Which are not very common to use, but I just wanted to know that they are there. So again, you pass a list here, and then what you could do is you could pass two dictionaries inside that list. So you can see the similarity. Here we used a list of lists. Here we are also passing list object, but it's a list of dictionaries. And, what you could do here is you could pass values, keys and values for a dictionary, and here as well. So let's say name John name Jack, execute that DF two. And yeah, this is yet another data frame. If you wanted to have more columns there, such as surname, you'd want to add here another key and value for the dictionary. So something like surname and now, if you execute that and DF two, you'll get the surname column added there. But for Jack, you get none because you didn't pass a surname in the in the second dictionary. So if you do the same for Jack, if you pass a surname, you'll get the value in here. So those are two basic ways to build data frames on fly. As I said, normally, these values will come out of files of CSV files, Excel files, et cetera. I will do that throughout the next lectures. And one more thing I want you to know is, this is a data structure, and now what data analysis mean is out of this data structure, you want to get out information. So you may want to extract, for instance, the average of all these values. So two, four, six, ten, 20, 30. So here we enter the phase of data analysis. And the approach to do that is, you know, this data frame object now, which you can see the type DF one. So it's a data frame of Pandas. Now, this data frame object has methods attached to it. If you do DR and yeah, you see that it has quite a lot of methods that you can apply to it. Let's locate the mean method there. Here is mean. So what you could do is you point to DF one and then mean and brackets, and you get the mean of all the columns. And if you want the mean of the entire data frame, you could apply again the mean method after that. So what this does is, it applies the mean method over this series here. So this type it's a panda series object. Series have more or less the same methods that you're going to apply to a data frame. So DF one and DF one dot Price, and you get the series of price column. So that is also if you check the type, that is also panel series. So data frame is made of series. And of course, you can apply the mean method to price as well. Similarly, you can apply other methods as well that are available there. So Max and you get the maximum value. And yeah, that's about the introduction to Pandas. Either next lecture, you'll learn about Jupiter. It's very pleasant to work with Jupiter. So don't miss that. And then we'll go ahead and open data frames, create data frames out of files. So I'll see you later. 80. Setting Up the Jupyter Notebook +: Well, in this lecture, I'll show you how to set up the Jupiter notebook or Jupiter for short, and also how to use it. So far, you've worked both with Python or an e Python interactive Shell, but also you've worked with an editor such as Atom. Sometimes you may have the need for a hybrid between an interactive shell and an editor when you want to test things out, but you also want to save your blocks of code that you're writing because an interactive shell is great for testing things quickly, but you can save the code, and the editor is good for saving the code, but it's not great for testing things. But I can tell you that such a hybrid tool exists, and that is called Jupiter notebook. And that is an amazing tool that will boost your productivity. Jupiter is especially good when you're working with data. It's a great environment to explore data, and you'll see its usefulness in just a bit. Of course, you still want to use editors such as Atom when you're working with multiple Python scripts that interact with each other. That's the case of web application, for example, when you're developing web applications, you'll have to deal with multiple Python scripts and also HTML file, CSS, and other files as well. Build web application later in the course and you'll see how atom is good for that. But for data, use Jupiter. So Jupiter, let's see how to install it. Well, you can go to the installation, so install and you can go through these instructions. But instead of going through this, I would advise you actually to use your command line to install Jupiter and type in PIP install Jupiter. So that we download Jupiter and it will install it in your system. And then to start a Jupiter session, a good practice is to go to a folder. Let's say, test three. And here you can open a command prompt, and then you type Jupiter No book. And that will open Jupiter session in the browser. So the Jupiter notebook is actually a browser notebook. The reason I opened the Jupiter notebook in the command line was that at least on Windows, when you do Shift and then right click on folder, your command prompt is opened in the current folder, so in this one here. And then when you create a notebook file now, every file will be saved in this directory here. Alternatively, you can open your command prompt everywhere you want, and then you can CD to the folder where you want to save your Jupiter notebooks. All right, now we don't have anything here. So what you can do is create a notebook. And we installed Jupiter Earth as a Python library. So under notebooks, we have Python three available. So the kernel will be Python three. If you have associated other languages here, you'll see them here under Notebooks. So this is an empty notebook. And this is the name of a notebook and you can change this to let's say, testing. Press okay. And if you go to the folder, you'll see that file with testing name and IPython notebook extension was created. So that is created automatically every time you type something here, you do some changes or something. Now, let me show you how you can work with iPython notebook. So you can consider every cell. This is a cell, and you can consider every cell as a line in a normal Python shell. But here in this shell, you can actually Write multiple lines of code. Let's say print one, and then if you don't want to execute this right away, you can press Enter. So with Enter, you enter a new line in the cell and then print two and so on. And if you want to execute the cell now, you can press Control Enter and you get the output. Now, if you want to create a new cell, Alt Enter would do that. And here you can write another block of code. With Enter, you go to the next line, and so on. And if you want to go to the next cell right away. So before we pressed Control Enter, now you can press Shift Enter and you go to the next cell automatically. And with Shift Enter, you also execute the cell where you were working on. You can create new cells with Alta Enter and you can delete them by pressing first, you press Escape, and then you press DD two times DD again. So it's quite flexible. Something you should notice is that we have two modes, basically. We have the command mode. So when you are in the command mode, you see a gray rectangle around the cell. And when you are to go to the edit mode, then you press Enter. So while you are focused on the current cell, you press Enter, and then you edit the cell. So in edit mode, when you type things, you're inserting text in the cell, you're inserting code in the cell, Escape and command mode, DD and you delete the cell, enter, and you enter a new cell. So these are the most used shortcuts, keyboard shortcuts. But if you want to know more shortcuts, you can go to help and then keyboard shortcuts. And then you see a list here. But these are good to get started. When you're done with this, you can just close a tab and you can also close the directory tree here. So notice that Jupiter actually opens in a local host session. And if you want to open again your notebook, you can go here again and go to open Command Window here and Jupiter notebook. And here is the file, and it's just as we left it. Now, a Jupiter notebook is best used for doing explorations and especially data explorations. So if you're working, let's say, with data analysis or data visualizations, the Jupiter notebook is perfect to use. You can use the Jupiter Notebook, for example, to load a table of data in the session. For that, you'd use pandas. So you import the library, you press Enter or Shift Enter to go to the next cell, and you press Enter again to write something. So let's say DF equals to Pandas, Dal Fred CSV. And I have CSV file somewhere in my system. Press center and Whoa. So you get a nice HML table which was loaded from the CZ file, and you can also plot graphs in the Jupiter notebook. So that's also something you're learning in the course. And so data analysis and visualizations, you can also use the Jupiter notebook for web scrapping. That is very convenient because you have these blocks of code and then you'll have to continuously tweak the code so you may want to change something here, and then you get a nice display. Not this one exactly because this is a messed up string, but this one, for instance, you have a slider here, so you can scroll up and down inside a separate window that doesn't affect your general your main window. So I hope you've gotten a good idea of the Jupiter rulebook. Just take a note of shortcuts of keyboard shortcuts to execute code, the edit and the command mode, you know, Enter escape and Enter again and so on and so forth. And you just practice them a little bit, and you'll get used with Jupiter very quickly. See you in the next lecture. 81. Loading Csv Files in Python: Now that you have a basic understanding of pandas and you know how to use Jupiter notebooks, we can go ahead and learn how to load various kinds of files in Python, using pandas and Jupiter. So I've got five files here. They contain exactly the same data sites. And this is a text version, or let me open the Excel version that will show a pretty overview of the data, as you can see. So we've got seven lines of code, including the header, and we have also seven columns. So it's just some basic data of supermarkets, the address city state country and the name of the supermarket and number of employees. And similarly, we have exactly the same data, but in different formats. So we have CSV and CSV means comma separated values. So it's basically a text file where the values, the columns are separated by commas, as you can see here. So every column is separated by comma. But it has a CSV extension, and it can be opened with Excel. So if I open this now, you'll see the same dataset that you saw in the ELS file. We also have the same data in separated by semi columns, as you can see in here. And yeah, if you're working with data, you're probably familiar with these kinds of files. So this is how to store data. You need to have some conventions, and using such convention, then you use other programs such as Python to load these data. So when you load CS file, Python knows that the values will be separated by commas and it knows how to separate them. It knows how to extract values. So we'll open all these one by one. We also have a JSON file. Which is yet another format to store data, and it looks like Python dictionary, actually. So we'll learn how to convert them to Panda's dataframe, as well. So all these will be converted to Panda's dataframes. Yeah, I'll go ahead and start Jupiter Jupiter notebook. Here are my files. I'll go ahead and create a new Jupiter notebook for Python three. Before I go ahead and load those files in Python. There's a trick I do usually. Import OS and then s dot list there, and I'll Enter, execute that. You go to the next line. And what you get is you get a list of files and folders as well of file names that you have in the current directory. So now I don't have to switch to my folder to look at the names. I have everything in here. Now I can go ahead and import Pandas. And let's start loading these files one by one. Let's say DF one, so data frame one, and that would be equal to Pandas. I'll read CSV. And then you have to pass the name of the file that you want to open. Supermarket the CSV and just enter and maybe you want to print that out. So DF there. And yeah, what we got here is so we loaded the data frame first, and then we printed that out. So we got this nice table in there. That's how easy it is to load data from CS file. Now, the benefit of having the data in Python is that once you load them in Python, you can do many, many operations with your data. You can do statistics and add new columns. You can merge columns. You can add the numbers of one column to the numbers of the other columns. And at the end, you can export those data back to formats like CSV, Excel, et cetera. So we're going to do that later. But first, let's see how we load data from several file formats in the next video. 82. Loading Excel Files in Python: And let's go ahead and load the Excel file Excel X, actually, an Excel file. So Pandas read Excel and you pass the name of the Excel file. And normally you should also pass another parameter here for Excel files because, you know, Excel files might have multiple sheets inside of them. So you want to specify the sheet name which starts from zero, so you need to pass index actually. If you want the first sheet, you want to pass zero. If you want a second sheet, you want to pass one and so one. So I'll pass zero there. I had only one sheet in the Excel file. D three execute. And, we were able to successfully read the Excel file as well. So let's move on. 83. Loading Text Files in Python: Yeah, let's move on with the TXT file. So it's a supermarkets separated by commas. So it's a data structure separated by commas. For that, so for TXT file separated by commas, again, you use R CSV. Just like that, D four. And here is the data frame. So the supermarkets CSV actually some say it's a comma separated file, but to be more accurate, you would say character separated values. So C is for character. And, there might be different characters there. In this case, when you have commas as separators, you don't have to pass any separator parameter here. But when you have other values as separators, you will have to pass that. That is the next scenario. So DA five, pandas dot red, CSV. So we're talking about supermarkets, semicolons, or supermarkets, semi colons dot TXT. Yeah, let me try this SIs now. So if I execute that, Python will not be able to recognize the semicolon there. The reason for that is because the separator parameter has a value of comma by default. So you want to change that to your separator, which is a semicolon, in this case, execute. We got an error there, unexpected keyword argument separator. So it seems like read underscore, CSV doesn't have a separated separate parameter. In that case, you want to do to ask for help. So yeah, here is the parameters that you want to pass. So it's actually a SAP, and you can see that the default value of SAP is a comma. So close that and go here, change that to SAP, execute, and here is the data frame. Great. What's left to do? Yeah, we consumed everything. And that's about reading local files. 84. Introduction to Numpy ++: Consider this gray scale image. Now this image is made of pixels. This particular one has three by five, so it has 15 pixels. So it's quite a small image. Now, each pixel has a value, and that's what defines the intensity of the gray color for each pixel. In reality, these are numbers, but our computer display shows them in a color format, which is a readable by us humans. What I'm trying to get is that programs use numbers to store images. Then the computer display or the screen converts these numbers to colors. Python can also do image processing, just like Photoshop does. Probably it cannot do all the cool stuff that you can do with Photoshop, but you can make use of Python to automate things. For instance, we'll be using the image processing capabilities of Python to detect faces from photos from images and also detect moving objects in videos as well. So videos are made of images. So it's the same thing, basically. And Python stores and reads images using arrays of numbers. For instance, this image could be represented as you know, a list of three other lists. So three list because we have three rows there with pixels. Then in each of the lists, you'd have like five numbers and so on and so on, and the fifth. And the same for the other two lists. We've got five numbers because we have five columns, so five pixels for each row. And that's an image for Python. And here is where Numpi comes in handy. So while you can represent images with is as we did here, this is not very efficient because for big images, is occupy lots of memory, and therefore they slow down operations on them. So this is solved by Numpi which is a library, a Python library that provides a multidimensional array object. So let me go ahead and create this array object. First of all, what you need to do is you need to import Numbi. And if you have installed pandas, numpie should have been installed with pandas because pandas is based on numpie. If you have an installed Numpi just yet, just go ahead and pip install Numpi. And if for some reason you have some problems on Windows, then just go ahead, as I've showed you and find the pre compiled Python libraries. Go to this side and then search for Numpi then figure out if you're on a 3.5 version of Python let just get that version. And then you point to this file with Pip Install and the name of the file. Great. No, I have num pi installed, so I'll create this multi dimensional object and store it in variable. That would be numpy dot A range. And let's say 27. Execute that and printout so this is a numPi array. That's how it is called. This particular one is not exactly a multi dimensional array because it only has one dimension. So it's a plane it's like a plane list, a Python list, but still it's not exactly the type. Sorry. So it's a nPi N dimensional array. It can have one dimensional, two or three. So we have one, two, three, and I'll show all these scenarios. So that was the one dimensional array, and if you want to print it in a nice form, that would be the array. Now, I'm just creating numpy array using numbers on the fly here, but normally you'd have to create a ray from images, and we'll do that in just a bit. So for now, let's create some arrays manually. Now, let's see what two dimensional arrays. V shape three by nine. So we already have this one dimensional array, and we want to convert it to a two dimensional array. If you execute that, you get two dimensional array. So that's a two dimensional array because it has two dimensions. So think of it as this image fall. We have two dimensions vertical and horizontal. Now, what's a three dimensional array? Even though three dimensional arrays are less frequently used, it's still good to know about them. Anyhow, let me create a three dimensional array. I could say three by three by three because you know you have 27 elements, so three by three by three gives you 27. Yep, that's a three dimensional array. Think of that as a cube that has three dimensions. So three by three by three. And practically, you'll see that in just a bit in this lecture. Where do we deal with three dimensional array? So bear with me. And you're able to see the similarities between non Pi array and plain Python list of lists. So this here would be like a two dimensional array, if you like to call it like that. The structure in the low level is different between Python list and nPi arrays. And also Nopi arrays allow you to make some more efficient operations such as iteration between array items and so on. And you can also create Nopi array out of Python list. For instance, I'll get this list here and I'll create a new object, and then point to nupi and to convert a list to np array, you'd want to use a array method. And then between the brackets goes the object that you want to convert. M and that's an array, which is almost exactly like this one in here. And if you print that, you wouldn't be able to see the difference. You know, they look exactly the same. But they are not because this is a list, and this is a numpy. Alright. Great. Let's move on. So that's Napi and as I mentioned earlier, Napi is a base library for other libraries such as Pandas and also OpenCV, which is an image processing library. So Pandas data frames are based on Numpi arrays, and open CV objects are based on NuPi arrays. So Pandas what Pandas does is it just adds some cool features. In there, such as it adds. It gives capabilities for having table headers and indexes, which you can't have in Numpi because Numpi is meant to be more simple and in a more low level of storing objects and doing operations. And so Numpi is a requirement for many libraries. Anda let's solve this lecture in here, and in the next lecture, we'll go straight ahead and create a NumPi array out of our image in here. So this image. Okay, see you there. 85. How to Convert Images to Numpy Arrays: And yeah, CV two is installed. And what I can do with Civ two, among many other things, what I can do the very first thing is to load an image in Python using CV two methods. So I'll be loading that image, which is a very small image, by the way, I only has 15 pixels. You know, a normal image that you used to take pictures or on your phone or whatever. It has like 1,000 by thousand pixels, which is 1 million pixels, more or less. But we should keep things simple so you understand what is going on. CV to import that and yeah, that was successful. You know, I'll create a variable and call this IMF image and G for gray. You can call it whatever you want, and CV to lead an image to load it in Python, you want to use image shared method. And then you pass the name of your image. You can find this image in the resource section. So just go ahead and download it. And now this is here in the same director with my Jupiter notebook, so I can go ahead and point to the name of the file including the extension, small grade dot PNG. And here the image read method also expect one other argument from you. That can be either zero or one. So zero means you want to read the image in gray scale. And if you pass one, you reading the image in BGR, which means blue, green and red. And you'll understand what each of the versions mean. So let's do this one first. Yeah, I'll print that. And how, that was it. So what we got is np array. It's a two dimensional array, so it has dimensions three by five, which is the same as our image. The rows and five columns. Now, the reason we pass zero there, so we're reading that as a grayscale image is because, you know, this PNG file in reality, it has three bands or you can say three layers. And each layer has a certain amount of colors. So the first layer has a certain amount of blue, and the second layer has a certain amount of green, and the last layer has a certain amount of red. So combining each pixel is a combination of the intensity of blue, green and red. I know in other programs they use RGB in opposite we use this BGR now, practically, this file here, this image practically is a grayscale image. However, each of these pixel has its own bands, so the combination of them always creates, in this case, the gray and white and black colors. But if we had a color image there, this would convert it to a grayscale this function. So again, what we have here is you know, 187 is value intensity for this first pixel. And then you have the other number, and for white, you see white here. We have three white pixels. And those are 255, all of them. Ay colors range from zero, zero would be black, pitch black, and 255 for white. And everything between them is in the gray scale. So now if I change this 21, I'll get the three dimensional array, where this represents the blue layer, the green, and the red. Or you can even print that out. Be careful, though, that this is a bit transposed. So the matrices are three columns in here and the rows are vertical. Basically, what this says is this pixel has these corresponding values. So it has an intensity of 187 for blue, 198 for green and two oh nine for red. And yeah, that's how you create numpi arrays out of images. But how about the other way around? So creating images of numpi array. Well, to do that, you do cv two again, cv two, and then you'd point to the Iriz method, so image. And then you want to pass a name for your image. Let's say, new small gray dot PNG, and then of course, you need to pass your no pi. So let's pass image gray. Execute that, you get two, which means that your fall should have been created now. Yeah, new small gray. And Yeah, that's a foil and I hope that strengthen your knowledge about Nopi. Now we'll go ahead and do some more things here. And specifically in the next lecture, we'll learn how to do indexing and slicing and iterating of Nopi arrays. So basically, you'll learn how to access these values. See you there in the next lecture. 86. Indexing, Slicing, and Iterating Numpy Arrays: All right. You know how to slice list. So zero to one, we'll give you the first item of the list and zero to two, the first and the second item of the list, and so on. With non Pi arrays, you do basically the same thing, except with non Pi arrays, sometimes you have two or more dimensionals or three. So let me go ahead and I'll create I'll start with a two dimensional array. So I'll get that from the variable. So this is the nonpi array that we'll be working with. And yeah, if you want to extract this number here, here, this one, and this. So these four numbers. Well, you'd first need to set the index of the rows that you want to slice. So that would be zero to two, which gives you the first two rows. Actually, we can try that. And you'll see that you get the first two rows. Now, if you want only this portion here, so these two numbers and these two, you'd want to pass. Comma there, and then the index for the columns. Which would be, you know, zero here, one, so two, three, yeah, two to four, maybe. Yeah. But you do it. Ah, that's it. That means you have this indexing system. So it starts from zero for rows, and then the second row is one and two and so on. Four columns, the same thing. Zero, one, two, three, and four. And actually, if you like, you can see the shape of your n by array. So it's three by five, which means zero to two and zero to four. Great. And of course, you can use the convention of list indexing, so you can pass zero and everything after that or just like that. So you get all the rows and only columns 2-3. Similarly, you can get only one value if you like. Not particularly this one because three is out of the bones for axis zero. So axis zero is a horizontal axis, which says that there is no row with index three. So we set zero, one, two. So let's pass two there. And you get 182, which is the very last item of the Nopi array. Yeah, that's about indexing. How about iterating through a Nopi array? Well, there are two ways to do that. The first way is to say, let's say for I in your Nopi array, print I. What that will do is it will print out the rows of your numb arrays. So what this I accesses in your number array is the rows. So in each iteration, it gets the first row and it prints it out in the first iteration, then the second one, and then the third one. And if you want to iterate through columns, you'd want to access the transposed version of your numpi array. And that's how you do it. Lastly, if you want to iterate value by value, you'd say for I in image and dot flat print I. So this property, what it does is it allows you to access values of your numpi array one by one. And that's about indexing, slicing and iterating. I'll see you in the next lecture. 87. Stacking and Splitting Numpy Arrays: Right now that you know how to do slicing and iterating through numpy arrays, let's do some more specific operations. And that would be stocking nPi arrays, so concatenating numpy arrays to each other and also splitting a numpi array two smaller arrays. Yeah, I have this numpy array still here. So let's start with stacking two numpy arrays. To do that, you may want to create a new variable where you'll save your big array, and that would be equal to nupi and the method to stock two non Pi rays, actually, there are two methods. One is horizontal stack, so H stack. That expects from to pass two or more numpy arrays that you want to stack horizontally. So let me pass OMG, and then the same array, it's not a problem. If you had two different arrays, you could do that, but I'm just passing the same array there. Now, if you execute this, you'll get an error, and I want you to see this error so that you understand it. So it says H stack takes one positional argument, but two were given, which means that H stack inside the brackets, it gets only one argument, but we're passing two. So how do we go about concatenating two non Pi arrays? We can just pass one non pi array there. So the solution here is to have a tuple. Of Nopi arrays, just like that. So a topple inside the input of the A stack method. You execute that. And here is a stacked array. So this is the first array, and the next array, which in this case, happens to be the same one, but if you want, you can add more and you get a longer array, which is not very good looking like that. So you can print it out. And yeah, now you see the difference. So the first array, the second and the third one. And if you want to stack vertically, you'd want to do V there. Oh, yeah. As you expected, this will concatenate the arrays in the vertical position in the vertical axis. Beware that if you try to concatenate arrays that have different dimensions, you'll get an error. So IMC has three dimensions, if you can remember that from up here. Now, you learn how to concatenate and how about splitting an array into smaller arrays. Well, to do that, you could create a variable and then numpy horizontal split for splitting horizontally. And this expects numpy array and how many arrays you want to produce out of that. So horizontally, let's say three. Right. And yeah, this says array split does not result in an equal division. The reason to that is, you know, we try this array has one, two, three, four, five columns. So you're trying to divide five by three. An umpi cannot decide how to do that. So should it give to you an pi array with these two column first, and then another umpire with two columns, and then a last nPi array with one column. So numpi cannot do that. What you should do is maybe five there, and L T m I should give you five different numpy arrays, which in this case happens to be one array for each column. And you can do vertical splitting. This time we can try three because we have nine rows there. And yet, we get three small arrays. Note that this LSD, so the split, what it produces is a Python list of numpy arrays. So it's a plain Python list. And out of that, you can access each of the nub rays if you like. You know that. So it outputs the first array. And yeah, that's about concatenating and splitting numpi rays. Hope I give you a good overview of numpi. I try to do some practical examples like opening images. But this is still yet in the theoretical part. So Napi is quite theoretical, and you only understand it when you get to use, like this. Real examples like working with pandas as we did previously in the course and also working with images. So we're going to do some hard core image processing in the next lectures in the next section. And you'll see how num pi comes in handy in there. And yeah, I hope you enjoy this, and I'll see you later. 88. App 1: Web Map with Python and HTML +: Hey, Hi again and welcome to this new section of the course in this section, you're going to build the second application of course. Specifically, what you're going to build with Python is this webmap that you see here. A webmap is a map that is displayed through a browser and can be visited through the web. This map was built with Python and volume. Folume is a Python library, and the map has three layers. It has a base map layer. The one that you see here with these names on the back and it has a polygon layer, which represents the population of the countries. Also we have this point layer here with these dots and you can turn on and off these layers. We also have these pop up windows. This is what you're going to build. A, let's go ahead and do this. See you in the next lecture. 89. HTML & Python: Creating an HTML Map with Python +: Hi, again, I hope you follow the previous video where I presented to you the map that you're going to build in this section. That was a web map, and as you may realize to build that webmap, the default Python installation is not enough because logically, a Python cannot have every possible functionality by default because if it had all the functionalities, then Python would become very heavy. Therefore, it is a smart choice to have external libraries that you may choose to install or not. And this is the case of web mapping. To build the web map that I showed you in the previous lecture, you need a library, a third party library, which is called volume. As you may realize you need to install that library. Now, just note, I had some previous videos about this section, some old videos, but I had to change them. I'm recording new videos now. This is a new video, updated video, and all the next videos of this section because volume had made some changes in the code compared to the previous versions. Therefore, I had to remake the videos. Now, this time I'm using a Mac computer, but that will not make any difference. If you're on Windows, Linux or Mac, everything will work exactly the same. The only difference is the way you open atom, of course. On Windows, please create an empty folder where you'll be keeping the files for this project. My folder here on Mac is mapping on Windows, you can hold the shift and right click. And then go to open atom here to open atom in this folder. On a Mac, you can press Command Space, atom then go to View Developer open in Dev mode and then locate the folder and click Open. Yeah, that's it. I'm going to close all this let me open the terminal and now go ahead and install volume. To do that, you need to type install volume. Normally, you'd have to do this on Windows. On Mac, if you have two installations of Python, you may need to do PIP three. That will explicitly say to install volume for Python three. Volume was installed successfully. If you have a message saying that Gina two is required for this package, then just go ahead and do PIP three install Gina two. However, I expect that volume will install Jinja two by default as it did for me, so it should be good to go. Once you've done that, I'm going to open Python, actually, Python three. On the map, you need to specify Python three explicitly. What I'm going to do now is I'm going to create a basic webmap I'm going to use Python interactive shell for that so that I show you things around. Try to import volume. Have no errors, that means volume has been installed successfully. Now, how does volume work? Well, everything spins around a so called map object. The very first thing you need to do once you import volume is you need to create a map object. I'm using a variable to store that map object and then equal to volume dot MAP. This is the class that creates this object. If you want, you can actually check the volume to get a list of available objects that you can use on volume. Here is map. Ignore the others for now, we'll go through them later. You can also ask for help now, volume dot map to see what you can pass to this map object. Create a map with volume and leaflet dot Gs. What volume does is it actually produces, you use Python, you write Python code and that Python code will convert automatically to JavaScript and HTML code and CSS code. Because you need Javascript, CSS, and HML to create webmps. You cannot do that with Python code directly. The browser reads HML CSS and JavaScript and renders the code of these three programming languages two elements like text and lines and points and pictures. That's what volume does. That's a wonderful thing that you can do that with Python through Python. Anyway, you can look here down here in parameters. You can pass a location parameter in here. And you can specify the width. Anyway, if you don't specify the width, a default width of 100% of the browser area will be used, you don't have to pass width and height as well, and then you have tiles, default is Open Street Map tiles. Tiles is a background of the map. You're going to see that in a minute. You have other parameters as well, which you can look by yourself, I believe. I pressed Q to exit the help and let's go ahead and create the map object. Finally, volume dot map. So location, you need to pass a location parameter there so that the map knows where to open. It may open, let's say near Alaska or near Greenland or South Africa. We're talking about the initial view, but then you can zoom in and out. Let me pass a random location. Locations, by the way, are given through coordinates by default, you need to pass geographic coordinates, which is latitude and longitude. Latitude ranges from -90 to zero to 90. So let me pass 80 there. By the way, this goes inside the list actually. 80 a comma and then the longitude, the longitude ranges from zero to -180 and zero to 180. Let me pass -100. And close the bracket. You pass a list of coordinates to location. Actually, that's enough, you can have a map object with that execute, you don't get an error, that means everything is working fine. Now you have a map object, but that's just an object inside Python. You haven't translated that object into HTML and CSS and JavaScript code just yet. What you need to do next is point to that map object. And then use the save method and then pass a name for the map file that will be created. Of course, the maps will be created in HTML format. HTML is what contains all these elements that render all the browser. Text and visuals and so on. Close bracket, execute. As you see, a file was added in here, map one dot HTML. But let me go to folder, double click that, that will open in your default browser. So this is just a random location. I don't know what it is. Magan Island. That seems to be in Canada, very north of Canada. This is it. This is the web map. If you zoom in, you'll see more details on the map like that. The more you zoom in, the more elements you see. That's what I wanted to show you. If you want another location, you'd want to change the coordinates in here in location. But if you don't know what coordinates your favorite place has, then there may be different ways to discover that, but a quick way is to go to maps.google.com. Let's say you want to know that let me zoom in here. You want to center the map around this location, right click there and go to What's here, copy these coordinates, copy those coordinates, or if you cannot copy them just remember them? 38.58 approximately minus 99 times 09. Then you need to save the map again, map one dot ML and that will override the previous map. Go here, reload, you see now we have a different center of the map. Of course, you can also play around with the Zoom, so you can add a Zoom parameter in here. This is called the Zoom start. Let's put it at six. Don't forget to close the bracket in here. Execute upper arrow key to call a previously executed statement like map save. You can also choose to go to the browser and reload with Control R or Command R, and that will show you the new map with another Zoom factor. Anyhow, that's about it. Try to play around with this a little bit. In the next lecture, I'll show you how to add points to this map. I'll see the 90. HTML&Python Adding a Marker to the Map: Hi, again, and welcome to this new lecture. In this lecture, you're going to learn how to add points to the map that we built previously, which is this one here. All we have here is a base map, the Background map, which is a layer actually is a layer coming from OpenStreet Map service. So Open Street maps, they give you a layer. Actually volume will serve you this layer on the background through JavaScript. But you can also add other layers as well, other base layers and also points which you can add on top of the base layer. Let me go back to the code. This is what we wrote in the previous lecture. Actually, we wrote it in here in the interactive shell. But I just copy it and paste this in file so that we have it and that we can add more code now on top of this. Again, as I told you, you can do help volume dot map and you see you can add other things in here, such as here you have a parameters. You can add tiles. The default is open street maps, but if you specify another tile, such as map box bright and that has to be in quotes, as you can see in here, In the tiles parameter, this expects a string object. Location, for instance, it expects a topple or a list, and that's what we pass passed a list of coordinates. The width would be an integer, an integer, the height. As a one, you have other options as well, which you can try by yourself. I just want to try this one for now. Let me open a new Python shell. Python three map one, make sure you have saved your script execute. Then you can go back to the folder and open map. Let me go to Farfox Control R or Command R to reload and you'll see that the background has changed, so we have a new base map now. Let's go back to the script now. What I'm going to do is I'm going to add some point markers on top of the basemap. How do you do that? Well, if you do the volume, here you can see that you have some objects and the one we want is a marker or a circle marker. I'll try them both. But I want to explain you the logic on how you add objects to the map object. In portfolio, we create a map object, and then between the map object and the safe method of the map object, you can add elements objects to that map. What I want to add in this case is a marker. So I can do map add child. We use the Adil method to add children. These objects that I'm talking about are referred to as children when you add them to the map. Map adchild and then you want to point to the volume marker. Now, this marker method, this expects some arguments itself. You can do help volume dot marker. Create a simple stock leaflet marker on the map. Leaflet is the JavaScript library that helps you to visualize this. That is the engine that creates those maps on the browser. Python creates a JavaScript code using the leaflet library and markers allow you to add pop pops. When you click a marker on the map, it allows you to show information and parameters you need to pass a location parameter to the marker in order to visualize it. So location equals two. It's a typical list. Let's say, 38 dot two and -90 91 and you can also pass. After the list, I pop up poometer which could be high. I'm a marker. I also need to pass the icon parameter, which actually is another object that comes from volume dot Con what you expect for me to pass a color there, like, let's say, green. Basically, that's it. Make sure your brackets are correct. I have three brackets here, three closing brackets and one and two, and three opening round brackets. Okay. Save a script, go to the other terminal and execute. Go to Firefox for load, and here is a marker. If I click, I get the pop up message in a nice window here. That's how you add markers to your map. However, I would suggest you follow a slight different approach to add children to your map. What I would suggest is to actually create a feature group volume data, feature group. But and you can give it a name like my map. Then what happens is that in this feature group, the marker is a feature with feature groups, you can add multiple features to the feature group. So you can add a marker, you can add polygons, et cetera. Instead of saying map, you do the feature group object, the variable that I created in here, I'm passing here. Then after that, you do map at child. And you pass the feature group in there. This is more. This is done to keep your code more organized, and it also helps you later when you want to add a layer, a layer control feature in your map to allow you to switch layers on and off. We'll look at this later. Save this script and let me try it. Pretty low the page. So we don't have any change. Things will work the same, which means feature group is working fine. But as I said, it's good to keep the call organized and it also helps you later when you add a layer control feature. That's what I wanted to teach you for now and I'll talk to you later. 91. HTML & Python: Using For-loops when Adding Multiple Markers: Great. We were able to build this map in the previous lecture. We have a base map and we have a marker feature here. This is our code. Now in this lecture, I'll show you how to add multiple markers to your map. The way to do that is one of the ways to do that is to write this expression multiple times. I like that, and of course, you need to change the locations of those markers. Save the script and execute reload, and so you have multiple markers. As you realize it's not possible to add multiple markers with one single method. With one single marker method, you need to apply the method multiple times. However, this is not very smart to do. That's the beauty of programming. You can use a for loop to actually add multiple markers to the map. We're talking about Python for loop, which is one of the fundamental features of Python. The four loop has nothing to do with volume. Let's say for for coordinates, of course, you would need some input with the coordinates. I don't know, like that. Let's say a list of lists. We have these two coordinates. Let me copy this. Put it there and another time and let me change them to nine and seven. Then you need to indent this with four white spaces. I'll explain this in just a bit. Then in location, you'd need to pass coordinates. Before explaining the code, let me try this out. Execute, go to reload, we still have the markers there. Of course, the location changed from the previous one because I changed the coordinates and here. So how is this working? Well, I'm iterating with a for loop through this list of lists. The items on the list of this main list are two other lists. The items can be anything. In this case, there are two lists. What happens is that the coordinates variable. In the first iteration, it will get this first item of the list, and it will put that small list, so 32.2 -99.1. It will put that list in here. Basically, this will be put in here. More or less. That's the idea. Then in the next iteration, coordinates will fetch this other list and it will put it in here again, and so the marker method will be executed two times. So the first time it will generate a marker with this coordinates and the second iteration, it will generate a marker with these coordinates. That's it. However, we have a small issue here. The issue is that in reality, you cannot just type the coordinates in a Python list. Let's say you have 1,000 coordinates that you need to map into a map and it's hard to type them in here or even page them, copy and paste them from document in here. The solution to that is that your coordinates normally in real life, they will come as maybe a text file, like a comma separated text file, CSV, Excel files, et cetera. You want to load that file into Python, and then you want to add the values of that file into the marker method. You can do that using a for loop and how you do that exactly? Well, I'll explain that in the next lecture. I'll give you a comma separated file with lots of coordinates, and we're going to use that in this script. I'll talk to you later. 92. HTML & Python: File Processing by Adding Markers from Files: Hello. In the previous lecture, you were able to build this map with multiple markers. This map happens to have only two markers, but you get the idea and the script was this one here, so you can add as many coordinate pairs as you want in here. But in this lecture, I want to show you how to add pairs of coordinates out of a text file, which is this one here, volcanoes dot TXT. If you like, you can just rename the name of this from volcanoes that text volcanoes that CSV, then you can open it in a program such as Excel. If you like, you can show it on a plain text file as I'm doing in here. Python can read both CSV and textfils. What we have here are some data about volcanos. Basically, we have the number of the volcano, which is some ID, volcano 020. We have yet another number then as you see, every column, we have columns in this data file and every column is separated by a comma. This is the name of the first column, the first value of first column is this one here, then is the name of the second column. The first value of the second column is this one here, then the second value of the second column is this answer one, and then we have a name column, the name of the volcano and here. Sorry, the name is here, Baker and then the comma starts here, which means that location is this one here, US Washington. Then you have status status historical for the first volcano and then we have the elevation, which is this one in here. I'm not sure whether these are in feet or meters, but you can find that out. If you're curious, you can do a research for this particular volcano and compare the elevation. Anyway, then we have a type of volcano. You have a time frame, which is D three, I'm not sure what this means, D four. Then lastly, this is where we are interested about. We have the lat and long columns. This is late, which means latitude and this is longitude of volcano. So you need these two numeric values in order to map the features, the volcanoes into a map, in this case, into a volume map. This has around 63, actually 62 63 including the header of the data. How do we load this fall into Python? Well, to load that fall into Python. Let me clear the terminal and you'd first need to install a very useful library called Pandas. We're going to use this library later on so I'm not going to explain pandas in detail for now because we will just using one or two of its functions, which I'll explain in this lecture. Go ahead and install pandas if you don't have Pandas. Install pandas or PIP three install pandas depending on how you have configured Python, and then you can go ahead and open a Python session. Import pandas. The way to load a file with Pallas is by pointing to Pallas that read CSV, volcanos TXT, make sure that your Python session has been opened in the directory where your volcano that TXT file is. For instance, my session is inside mapping folder, which is this one here, so I can just pass a file name. Otherwise, you may have to pass the absolute path of the file which starts from C slash and so on, depending on what operating system you are in and execute that and call data and you get the data printed out just like that. Panda is actually the read CSV math is able to distinguish between these commas, where the commas are, and it creates a web structured data format with columns. If you go down here, you have some columns here, column column, column and then up to the end. Then you have other columns because Python cannot print out actually, the terminal doesn't allow you to have all the columns in one inside this area here because it would be too much. Anyway, you have status elevation, type timeframe, lat and long. That's about the data. Now you need to figure out a way to iterate through that data frame. This is called a data frame. The data object is called a data frame. You can check its type actually. PanascFrame data frame. What I'm thinking of is to actually create two lists out of these data frame columns to put the latitude column in a Python list and the longitude column in another Python list so that we have a native Python object, which is a list, and then we can iterate through that list using the four loop. Let me try to do that. Import Pandas, then create the data frame object. Loading the data, I read CSV volcano TXT, that's it. How do we convert a dataframe column into a list? Well, the way to do that is by just doing let's say L or T egal data and then the name of the column, which is LT so you can get a list of columns by the way, by doing data dot columns. Here you see, you have a lat and a long column. Then you do that equals to list on in square brackets, close it. What you did here is data with a lone attribute there, we return a serious object. But that serious object, we're converting it into a neative list. That will be a Python list. This will also show up as a similar object. This is a serious object. This is a list, but I prefer to work on a list because working on lists is faster than working on data frame series. The idea is to have two lists here. That equals to list on copy that pasted here, the same thing goes for longitude. Lat and long list. So we need to be careful here on how we iterate through these two lists because what we have is we have two lists and each of them has 62 items. You can check that using an here, down here, that so it has 62 items and the same goes for the longitude list. That means that the first item of the latitude list corresponds to the second item of the latitude list, sorry, of the longitude list. The first two items make up the first location of the first marker. That means that in the first iteration, we need to extract both locations. Actually, this structure won't be appropriate anymore. What you need to do is you need to go through let's say lat and loan variables. When you iterate through two lists at the same time, you need to use the zip function and then it goes lat and lone. Basically, what this function does is like this. Let's say for I, J, and Zip. Let's say the first list is 123. The second is 456. Print, I and J. This is what happens. This loop will go through these two lists at the same time. What happens is that I will go through the first item of the first list while J will go through the first item of second list. In the first iteration, one and four are extracted. One, here, and four here. And you can do such an extraction by using the ZIP function. Otherwise, you won't be able to do that if you don't use the ZIP function. So ZIP sort of distributes the items one by one. And so the same goes here, LT will get the first item of this list. L one will get the first item of this list. And then here, what you need to do is you need to construct a list with LT and LN. Yeah, that's it. Save the script, go to the terminal to execute. It's not here, the terminal. I just exit that. Python three, map one dot f cut. No errors, go to Firefox and reload. I've got no markers for some reason, but I didn't get an error. This is one of those scenarios where you don't get an error in the terminal. In that case, you need to double check your code carefully. Data panels three CSV, let is data alone. Here's the error. What's happening is that I'm assigning the wrong column to the latitude list. Let me change the order and try again. So don't get intimidated by errors. Errors happen all the time. You just need to be cold blooded and read the errors if you get any error here and also look at the code carefully. Let me reload. I've got some markers now. These are the locations of volcanoes in North in US, actually, United States. Okay. They also have this pop up, which is working well, but I assume you don't like it very much because it's not showing any information. What we need to do here is to actually make this pop up dynamic so that it shows some actual information. I'll show you how to create dynamic pop ups in the next video. Talk to you there. 93. HTML&Python: String Manipulation: Hi, again. In this video, I'm going to show you how to add the elevation values. These ones in here to the pop up window. Currently, our script simply prints out this string in the pop up window. We're going to change that. The way you do that is by first loading the elevation data into a Python list. Then in the loop here, you want to say, let's say L in Z plat lone Lv like that. Here in the pop pop argument, you pass L attribute. Again, we create a list which is named F, variable LV. That will be a list of all the elevations and then we iterate through these three lists. LT will get the first item of let, LN will get the first item of loan, L will get the first item of LF and those items will be distributed in this function in here. LT in here, LN in here and L in here, EL in here. Now, I want to save this and execute, but I expect to get an error I want you to see the error so that you get familiar with handling errors as well. The error is happening on line 14. In this file, map one dot pi, which is our file, line 14 is here. This is a line and then we have at child Pop Up. It seems this error has to do with a pop up object. I'll say this is not a very good error message actually. It's hard to read this error and troubleshoot it. Not very good information given by volume here, but anyway, we have some clues. Pop this says name child name attribute or nupiFlow 64, object has no attribute, get name. It seems that volume is trying to apply these get name method, which is a method inside the volume code base, and it's trying to apply it to a number. I think that this L here is actually a number. I can check that by saying print type, save execute the script Again, here is a type. This is a num pi float 64. Basically, it is a float type. It's actually a special float of numpi library. But anyway, you can call it a float. So it's a number, it's not a string. But if you look at help sorry, help volume, dot marker, you'll see that the pop up parameter expect a string from you as input. But instead, you're passing a float number. So you don't want to do that. What you want to do is simple, you simply convert that flow number to a string. Save the script. Go to the terminal. Execute again. Go to Firefox, reload, and you get the elevation displayed correctly. Yeah, that's about it. You can you may also want to stylize what you're displaying so to add more information there, such as plus space meters. I'm adding the string to every pop up window information for all the elevation numbers. We're talking about 2,447.0 meters. That's the elevation of the volcano. Yeah, that's the idea. I hope this was clear and I'll talk to you later. 94. Using Functions - Creating a Color Generation Function for Markers ++: Hey, Hi Again and welcome to this new lecture. What we have so far is this map with these 62 markers, each of them representing a volcano location in the United States. However, this map is not very smart, so to say, the only information that this map conveys is the locations of the volcanoes. And you also have a base map. There's also a good aspect of this map because you can extract information like that if you click the icons. However, you may want to transform this map to actually show an attribute instead of just volcano locations. The way to do that, there may be different ways, that's up to your knowledge about cytography, but I could make the map show an attribute here. For example, I could change the colors of these markers to actually show the elevation range. Let's say we can categorize these markers into three colors. Let's say green, orange and red, green would be for elevations 0-1 thousand meter, for example, or 2,000 meters and orange would be 2000-3 thousand meter, and then red markers would represent volcanoes with an elevation of higher than 3,000 meters. So how do we do that with volume? Let's get back to atom. Here is our code, what we have so far. Currently, what we're passing to the icon argument is a color argument with a value of green. Basically, what we need to do, we need to make these dynamics so that the color changes depending on the elevation. Unfortunately, we cannot do that with volumes. Volume doesn't have native functionality to create dynamic colors for your markers. Therefore, we need to be a bit creative here and use Python core functionalities to do this. When you think about dynamics, I think about functions. Basically, this loop is going through latitude, longitude elevation and then it passes those three values into this expression in here. However, color is being passed a string always. But how do I change it depending on the elevation, for instance? Well, the way to do that is by creating a function, a function that gets as input elevation and then it does some actions inside the function, then it returns a color depending on the elevation value. You can say, if elevation is less than this, give me green color, a green string here. And so on and so forth. To give you an idea, the way this would work is, let me write the function here. This would be a good place to do that before creating a map object. But always always you need to create a function because I'll be calling the function in here, so you need to create the function before this expression from here and upwards. I'll be creating that in here. Let's call a function call a producer. Let's keep it simple for a while, just to Demonstrate you how this would work. Let's keep it very, very simple. Let's say return green. If you change this to color producer and don't forget the brackets, by passing brackets, that means you are calling the function. If you don't pass the brackets, that means you're just calling the function name and you are not executing the function. I'll just keep it like that and go ahead and execute map one dot pi. All right. Reload and you'll get the same thing. Because what happens is that. This thing here, this function coal will be equal to whatever you return here. The type of this object is actually a string. It's exactly the green string. Therefore, now you can add some conditionals here. Basically, you need to pass an input here, elevation, let me write whatever variable you like, write elevation and here, you need to pass L. L for letlon L, let's say we have 62 rows in the data table and for loop will go through the first row of the table. It will get elevation and pass it to this function call. The function will pass L into elevation, then you say here, if elevation is less than 1,000 then you want to return green for elevation is less than 1,000 meters. A leaf elevation is between 1,000 meters, it's greater than 1,000 meters or less than let's 3,000 meters. Return orange. Else, return red. Red will be returned if none of these conditions is satisfied, which means elevation is neither less than 1,000 meters nor 1000-3 thousand meters. Which means what is left is greater than 3,000 meters. In that case, we will return red. For finding out those values, actually, you need to do a little bit of data exploration. For instance, you may want to look at the data quickly like that to see what values you have. And then decide on the category threshold. But you can also make more significant statistical analysis you can make a histogram and see the data distribution and then decide on these values. But let's keep things simple and let's decide on these values. I'll solve this check if everything is in place just quickly. Let me try the code. Go and reload. We have some different colors here. Yeah. This is looking good. Let me double check the values. For instance, orange is between 1,000 meters and 3,000 meters. We're doing good. The red is above 3,000 meters. It seems it's working. 95. HTML & Python: How to Add and Stylize Markers: All right. I hope you solve the exercise, but don't worry if your map looks a bit different from mine. Anyway, here are my markers, circle markers, actually. And I have green orange red and orange markers. You get the idea. And they also have some sort of opacity. So I've set an opacity value of 0.7, which means 70% to them. As you see, you can see the marker that is underneath this one here. Anyway, here is a code. Let me explain what I changed from the previous from the original code. I changed marker to circle marker. The location remains the same. Also pop up attribute remains the same. And then I added a radius here of six, which means six pixels. That's the size of those circle markers. Then I added a field color. The field color attribute is for the inner area of the circle. You see this orange area, but you also have this outer color here which I set to gray and you do that with the color argument. Color equals to gray for all of the markers. The default color will be black, which I think is a bit heavy for the eye. Anyway, here is a field opacity. For the transparency, I said it to 0.7, and that's it. I hope this is clear now and I'll talk to you later. 96. HTML & Python: Working with JSON Data: Hi, welcome again. In this lecture, I'll show you how to add another layer to this map. Currently we have two layers. We have the base map, which are map tiles by map box, you can see here, and the data are served by OpenStreet map and you also have your custom layer as well, which is a layer containing circle markers. In GIS geographic information systems, these are referred to as layers. Now I'd like to add a third layer to my map, that will be a polygon layer. This current layer with markers, this can be referred to as a point layer. You also have line layers and polygon layers. With points, points are better to represent locations and you have lines, lines are best for representing geographical features which resembles lines such as roads and rivers. Then we have polygons. Polygons are best to represent areas. For instance, in this lecture, what I'll show you is how to add a layer, a polygon layer that represents world population by country. Countries are represented as areas. And what we're going to do is each of the countries will have a specific color which will indicate the population of that country. Points for locations, lines for lines, and polygons for areas. Now, of course, you need to have some data to create a polygon layer. Just like as we did with markers, we had some data in CSV in text format. And then we use those data, we open them with pandas and then we iterated through those lines of the data and we added the markers to the map. Now, for polygons, the way to add polygons via volume is by using the volume dot GeoJSON method. Basically, let me make some space here, the way this would work is. You want to add to feature group variable here, you want to add a child, which would be a volume Geo JSON object. This is the method with brackets here. That creates a GeoJSON object. For GeoJSON data, we will use this world dot JSON file. You can find this attached in this lecture. Let me explain what this is, but careful don't open it on atom because if your computer is a bit slow, your atom may crash. Try to open it with a lighter editor such as Notepad, for instance, or CAT on Linux terminal or Mac. Anyway, this is the JSON file. You can refer to it as JSON or GeoJSON. Actually, GeoJSON is a special case of JSON. Basically, the format is always the same. It starts with curly brackets and basically, it contains a string which is like a Python dictionary with keys and values. Keys key and value where this curly bracket ends somewhere here, I believe, if I'm not wrong. Now, this one ends in here. Yeah. Then you have the other key geometry. What is geometry? Well the type of geometry is multi polygon. Basically, you have these attributes that describe the data. Type multi polygon coordinates. This is now starting to describe the features, the polygons. These are the coordinates of the first polygon that will be displayed on the map. Let's say this is one specific country that's Antigua and Berbuda. A small country, but anyway. These are the coordinates that will determine the location of the polygon in your map. Basically volume will read all this information and it will decide where to put the polygons. Then you can also use other attributes of this such as population, which is here, you'll use this population value to put a color for that population. And so on and so forth, you have all countries of the world in this JSON file. Spend a few minutes looking at this file to understand its structure. In the next lecture, I'll go ahead and load the JSON file into Python and display the polygon layer. See you there. 97. Python & JSON: Adding a Population Map Layer: Great. In the previous lecture, I showed you how a JSON file looks like. In this lecture, I'll go ahead and add that JSON file to the code. Remember, I provided you with the JSON file. In the previous lecture, you could download it from the lecture resources. So this GeoJSON method gets a data attribute which is equal to the file object of the JSON data. Basically, you need to create a Python file object which you can create with open. Remember, open is a classic Python method for creating file objects. There goes the path over the file. This happens to be in the same directory with my Map one dot py script. I'm just passing world JCO. I am basically opening it in read mode. I'll leave it like that for now, save, execute. I think we'll get an error here. Yeah, we need to add an encoding parameter there as suggested by the error message. That goes inside the open method. Equals to UTF eight SIG. Say again, go and execute load, and we have the polygons displayed on the map. That was quite easy to do. Something you should know is that you can also add points through GeoJSO. In this case, we add polygons, but that JSON file could also have lines or could also have points in its attributes. So this one we had an attribute that was stating, these are multi polygons, but this could be points or lines. In that case, volume will display those features depending on this type attribute in here. Of course, you'd also have the coordinates attribute with the coordinates of the line. The points where the line breaks and turn in the case of points, you would have pairs of coordinates here. I hope you get the idea. That was about this lecture. In the next lecture, I'll show you how to create a choropleth map, which is a map that uses coloring of areas to represent features. In this particular case, what we do is we will have these polygons with different colors to represent the population of the world for which country. We'll do that in the next lecture. See you. 98. Python & JSON: Stylising the Population Layer: Hi, again. In this lecture, I'll show you how to make a country by population map. We'll be showing population of each country through graduated colors. So we'll think about a range of colors to represent population from low to high. We have that piece of information in our w dot JSON file, which is stored in this pop 2005 attribute. Pop 2005 means population from 2005, which is quite old, but it shouldn't be a problem for educational purposes. So let's get back to the code and the way to change the color of those polygons because by default, we have this green color. There's also transparency on the polygons. You can see the base map on the background. To change that, you need to access the style function argument. But I have messed something here from the previous lecture, which could cause some problems later. This doesn't have to be in around bracket, so delete that one here as well. So we have one, two, three open brackets and three closing brackets. Now, it should be fine. We need to add another argument to GeoJSon. This is the first argument. Data is the first argument which ends in here. Add there another style function argument, and you can actually break the line in here. You are free to break lines in Python when the expression is inside brackets around brackets, square or curly brackets. In this case, this expression is inside brackets, so we are able to break it and it's good to break it at the comma. Style function equals to, now this expects a Lambda function. Lambda functions are just like functions, normal functions, but they are written in single lines of code. For instance, let's say L equals to Lambda. This is a Lambda function X in power of two. Oh, sorry, I had a typo there, not and bub but lamb Another typo. A is a function here just like you'd have a normal function, and then you can call L. You can pass a value like five and that will return five in power of two. As you can see, you can write the function in one single line. This can also be useful in other cases like this one in here that you'll see in just a bit. Lambda X. This also allows you to write anonymous functions. This function, it doesn't have a name. Like here, I assigned a name to this function because I needed to call it later. But this one here, we don't need to call it later, so you don't need to give a name. Here, the syntax would be correct if I do just like that. Let's go ahead and do this. Fill color with a capital C, lowercase F, upper casc and That should be in quotes. Let's say, yellow. Now, if you want, you can leave it like that. Save the script. Exit the Python shell and execute the script. The execution went fine. Let me check the map, reload and you'll see that the colors of the polygons change to yellow. That's how you can change the attributes of your JSON file. To say, basically you add this attribute which is not in the JSON file if you search for it. You'll find nothing unser. Now you can play around with this by adding conditionals inside this dictionary, such as I X properties Pop 2005 is less than let's say 10 million, ten, one, two, three, one, two, three. What I'm doing here is I'm saying that set yellow to fifth color if X represents the adjacent feature here. If the properties actually if the Pop 2005 attribute of this attribute of this attribute which is here, this is Pop 2005. I know this is a bit complicated. Let me took a software wrap. Now I have all the text wraps here in the view and here Pop 2005 is actually part of this dictionary up to here. This dictionary, these are a set of properties. This dictionary is the value of this key of the properties key. What that means is that we are accessing the value of the propeller scheme using this syntax, which is known in Python. Meanwhile, X properties, what that is is X here represents features. So you are accessing properties from features. On the background, this is a bit of a black box but volume, what volume will do is it will go through all the features of all the polygons and it will check if the value of pop 2005 is less than 10 million, and if it is, then it will set this color to fill color attribute. That's more or less about it. I think it's better to put this green. If it's less than 10 million, put it green else Orange. If between 10 million, do the same thing here. Properties, actually, you can break the code in here. So properties Pop 2005 let's put here 20 million. These are just arbitrary numbers. You can put everything that you want, but that will affect how your polygons are classified are colored. For population 10000000-20 million, we'll get orange colors. Else red. Everything above ten will be colored as red. Save this and I hope this will work. No errors. Reload. We have US colored in red because it has a population of higher than 20 million people, it seems to be working fine. Yeah, Portugal Portugal has a population of around 12 or 15 million people. I'm not sure. It's in the middle range of our classification algorithm. An, that's more or less about it, and if you like, you can ask questions. I'll be happy to help you and I'll talk to you later. Thanks. 99. Python & JSON: Adding a Layer Control Panel +: Hi, and welcome again to yet another lecture on web mapping with Python and volume. This is the map we built this for and it contains a base layer, a polygon layer and a marker layer. This is our code. Now, what I want to do in this lecture, I want to implement a feature that allows me to turn the custom layers on and off. With custom layers, I mean the polygon layer and the marker layer because it's not possible to turn off the base map at least as far as I know. It wouldn't make sense to turn off the base layer. You don't want a blank page. So let's see how to do that. The key feature here is layer control class of the volume module, which can be added like this. You want to point to the map object that you want to add a child. Layer control is added as a child. Volume layer control. Now, this will not work. But I still want to execute this so that you don't make this mistake later on. Let me reload the page. You only see the base map here, no layers at all. The reason this doesn't work is that when you added layer control to the map, you still hadn't added the feature group, which is an object that contains the Jason layer and the marker layer. So basically layer control we'll be looking for the feature group added to the map, but it doesn't find it at this point. Therefore, things are messed up. It's important to put that offer you have added the feature group layer to the map right here. Execute again. Reload the map and you see the layers there and you'll see this box here. Map box bright. This is about the base map and you cannot turn this off. You also have this My map item here of the layer control panel. This is the layer control panel and you can turn on and off this layer. But as you see, this is turning off and on both the polygon and the point layer at the same time, which is something you don't want. We go ahead and change that. I'll explain why this happens. This is happening because layer control, what it does, it it looks for objects added to map with a child like here. You have added a child and you have added only one child to the map object. Therefore, layer control will consider that object as one single item of the layer control panel. But that feature group object, it contains circle markers, but it also contains the GOJ sum. Layer. Therefore, you need to change your strategy here. How can you do that? There may be different ways. One way is to actually create a feature group for volcanoes. Let's call it Fg V. You add GV here and then you want another featured group. Let me copy this line, paste it here. You want another feature group for population. Let's call this population. Let's call this volcanoes like that, change the variable name FGP, FGP here, FV there. Add an alpachild which has to be FG P for population. Now everything looks good. Let's see if layer control will be able to read these two feature groups now. Go and reload the map looks fine. Volcanoes working well, population too. Everything is working fine. This is a map. If you were able to build this as I did, then good job. You can also choose not to use feature groups actually. You could have added GeoJSON to the map directly. However, for this case for volcanoes where you are executing the at child method multiple times, in that case, you'd have one layer for every volcano. You would have added 62 children to your map object if you did map without feature group here. That means in this control panel here, you'd have 62 entries, 62 layers, and that's not what you want. Feature group comes in handy in here. For volcanos it is necessary. But for GeoJSON, you could have used map here and everything would be fine. But for consistency, it's good to add both to particular to specific feature groups. Volcanoes here and population here. So this is the code, and I hope you enjoyed this program and feel free to ask questions. I'll talk to you later on. See you. 100. App 2: English Thesaurus +: Hi and welcome to this new section of the course, and in this section starts the real deal. So in this section, we're going to develop the first application of the course. Until now, you went through the basics of Python. You learn functions, loops, conditionals, and handling files, et cetera. Now we're going to practice all those concepts by actually building real programs that can be used by users instead of just looping through trivial strings and numbers and so on. And so what are we going to build in this section? Well, you're going to build a program which you can give a word, an English word, and the program will return the definition of that word in English. So let me go ahead and demonstrate the program. I'm using Python three. App dot p is script. So the program asks you to enter a word, which you want the definition for. For instance, let's say Mountain. And so you get the definition for mountain. And in this case, it happens to have two definitions. So mountain mountain is a feature of the Earth's surface that rises high above the base. A, mountain has another meaning, which is a great number of large amount of things not placed in a pile. Anyway, there are words who have only one meaning like mathematics. I hope, yeah. So you get only one definition for mathematics. But also the program has other features as well, such as if you put AN with double N, so with an extra N and press Enter. The program instead of crashing, it displays a message. It tells you, Did me rain instead. So it's quite an intelligent program that guesses the word that the user had in mind may have had in mind when typing the word. So enter Y if yes, if you meant rain or N if no. Oh, yeah, I meant rain, so why? And you get the definition for rain, which happens to have two definitions. This is the first one, and this is the second one. The program will say, if you enter a very random word that doesn't have any meaning like that, you get the message, the word doesn't exist, please double check it because the program cannot find a similar word to this. It cannot find a word first. And also, it tries to find a similar word to this one, but it doesn't because I don't think there's a match for this. So it prints out this message. There's also other things like, you know, if you have mix of letter cases there like uppercase R and A, you still get the correct input there. So that's a program. It has a command line interface, which means you are input you're passing the input through the command line and you're getting the input again from the command line. However, later in next sections, I'm going to explain your web applications, how to create web applications with Python. So you then get back here and actually creates a web application using the code that you'll be learning in this section. So you can extend this program to make it more user friendly with a web interface where the users can enter the input through a web form, st through a web page and then press a button and then get the output on the web page. However, the code that you'll be learning in this section is very important. It's called Python. So you're going to learn about conditionals and loops. So you're going to implement all those that you learned in the previous section by developing this program. So I hope you like this and I wish you success. See you in the next lecture. 101. Understanding Your Dataset in Python +: Hey, hi again. In the previous video, I did a demonstration of the program so that you know how the program looks like and what is the output that the program generates. Also the interface of the program, which is a command line interface. You input the data through the interface, the user inputs the data through the command line interface and you get the output again from the command line. Now I have created a folder here somewhere and I have give it a name. You can give it any name that you wants inside this folder, I'll be putting all the files of this project. We're talking about the data files like data dot JSON. This is a file that contains a vocabulary where the program will extract, we'll ask for a word and this file has the definition of the word. And also the dot Pi files will be put in here. We know the output, now we need to figure out the way how to go to that output and we will take the approach step by step, which means that first we're going to develop a simple version of the program, just give the program a word and the program will return the definition of that word. But this will be very simple because the user sometimes they may pass a word that doesn't exist, and as a programmer, you need to count that word for that non existing word. Instead of breaking, interrupting the program, showing an error to the user, you need to show a more user friendly message to the user. I will do that in the next videos. But for now, the very first thing we need to think about is the data. So I did some research on the web and I found this dataset of words and definitions. Now, this is around 5 megabytes of data. In atom, it takes a while to open, so I clicked it and I still waiting for it to open. Now it opens. If your atom freezes, then you can open this with a more lightweight editor such as Notepad or Nano on Mac or VIM. So anyway, this is a dot JSON file. What is Jon JSON is like a language. Some say it's not a language, it's just a set of rules how to format some data. JSON follows this format. It starts with a curly bracket, then all we have is pairs of keys and values. This is like a Python dictionary. The key is separated by the value by a column. This particular case, our values are inside square brackets, which suggests that sometimes you may have more than one item inside the brackets, for instance. Let me search for the word control F or Command F. Rain. That will take us in here. First, let me go to view and Toogle soft wrap. What that will do is it will fit the text inside my screen. For the moment, you see precipitation is outside of the screen bonds. This also takes a while because we have quite a lot of data here. Now the data looks better, so let me search for rain again, find so this is the key rain, let's say, the word rain and this is the definition of rain. In this case, we have two definitions because for some words, you may have more than one meaning or you have more than one form. For instance, this is the rain as a noun, it's a precipitation and this is the verb for rain. When it rains to fall from the clouds and drops of water. It's a verb and a noun and they are separated by a comma. So this is just like a Python dictionary. Now we need to figure out how to load this data into Python. Because to access data from this file, you first need to load it into Python as a specific Python data type, and then you access data from that datatype. Think for a moment what Python data type would be more appropriate for this JSON file. Think about that and I'll show just that in the next lecture. See you there. 102. Loading JSON data in Python: So I believe it was quite easy to realize that the best way to load this data in Python is a Python dictionary. This looks just like a Python dictionary and once you load it in a Python dictionary, then it becomes very easy to access a value for a key. So how do we load this into a Python dictionary? Well, let me open a command shell here. For now, I'm just going to demonstrate something quick in an interactive Python shell. But first, you may need to close this JSON file because this is slowing down atom. Don't say the changes. I didn't do any change anyway. Python three, that will open my Python 3.6 0.1. But anyway, even if you have Python two, this program will work the same. So how do we load JSON into a Python dictiary? Well, for that, we need to use the JSON Standard Library. With a standard library, it means that you don't need to install JSON. You just need to go ahead and import it. Once you do that, there is a nice JSON dot Load method there. This load method, the expects actually, I can show it like this, help JSON dot Load This gets this argument here, which is a file like object that contains a JSON document. We're talking about a file object in Python, and we need to create the file. The way to do that is simple. JSON again do Load. The way we create a file object is by using the open method. You know that already. Then you pass the path to the file. Now since my terminal here is pointing to this folder, I just need to pass a file name. I don't need to pass any full path in there. Like that, you can either pass the R method, which stands for read mode, or you can just leave it like that and the read mode is by default. Make sure to close brackets two times. We have two opening brackets here, two closing brackets in here, that's all. Now what is data? Data is a dictionary. It's a Python dictionary and you can print it out. Yeah, it's quite a lot of data. That took a while, but normally you will not have to print out the entire dictionary. What you could check is to access a word a key from the dictionary. Let's say the key rag, you need to use bracket, sorry, quotes for the key. This is what you get, et the value for the word for the key arraign. Now that you know how this works, more or less, try to come up with a function that gets as inputs a key and then returns the value for that particular key, and also try to incorporate the loading of adjacon fall and also print out the output. If you have issues with that, in the next video, I'll show you how we do that. See you there. 103. Making the App Return the Definition of a Word: I hope you figured out how to create a function that gets a key, a word and it returns the definition of that word. Let me quickly build that program. Let me call this app Ones point in pot Jason. Data eg see JSON load, open data dot JS. That's it. Define the function. Translate, let me call this translate. Word, and all you have to do is return data word. That's it. Then you can either, let's say, you can either do something like word eagle to arraign or you can do this dynamically by asking for input from the user. Printer word like that, leave a space, and then all you have to do is print out the output of the dictionary. Because you know this dictionary for now, it just returns a string, but you are not printing any output. If you want to show that output in the command line, you need to print out translate word. That's it. Now, don't get confused with these variable names. This is a global variable and this is also a global variable. We define variable here and we pass it here. Then this whatever is passed in here goes to this one here. This could be a different word, a different variable name. So let's say W W. This is a local variable. It has a meaning inside the function and it can be everything. If you pass W here, it has to be W in here too. This passes this value into this value here. Usually programmers, they prefer to just enter the same name here and there. But for you as a beginner, I wanted to show you this difference that this doesn't have to be the same with this. Save the script, maybe open another terminal. Python three app dot pi, execute, Enter a word, Rig, and this is the output. How about these words? We got a nasty error there. But you don't want to show that to the user Because this is not very readable. Trace back most recent call last, how do we count for this scenario in our code? You need to figure that out. Think about it. Even next lecture, we'll do just that so we need to take into consideration that word that the user passes may not be in the dictionary set of keys. Rain was a key of data Jason dictionary, but this name was not, so we need to count for that. I'll show you that in the next lecture. See you. 104. How the App Deals with Non-existing Words: All right, let's go ahead and make this program more user friendly. Instead of showing this block of error, we're going to show a message that says the word doesn't exist, please double check it or something like that. The way to do it is, let me go to the Python interactive shell. You can check something like that rain in data and you get two. If you do this in data, you get false. We need to make use of this and say, if word in data, this has to be W. We're talking about this variable, so if in data, what you want to do is return the value. This is the value, and if this returns true, this is executed, s, return the word doesn't exist, please double check it. When this is false, then else is executed. Actually, the expression under else is executed, and this is not executed. As you see, this is quite readable, very humor readable. This is a good one of the great features of Python actually. I can save this now and go here, execute the program. Rain would work as before. And this says the word doesn't exist, please double check it. As easy as that. The program is taking shape. However, you need to do more tests to check for different inputs in order to take into consideration every possible input that the user may put there. Let's say the user puts rain in uppercase letters and this says the word doesn't exist. But actually, rain is the word that exists in your dataset. And so how do we count for different uppercase letters? You also may have mixture of letters like that, and it still says the word doesn't exist or even rain like that. The word doesn't exist. Think about that again and in the next lecture, I'll implement that, which is very easy. See you there. 105. How the App Deals with Case-Sensitive Words: Great. We have this program now that returns a value from a word that we put. I reasons the definition of that word. It also counts for non existing words in our dataset which is data dot JS. To count for different cases of letters that us may input, you may look at the dear STR should show you the methods that you can apply to a string. Here is there's a lower method. What that does is if you put rain there, it's, so the method should be applied with brackets. You get rain the lower version of the letter. Since our data are all in lowercase in our data dot JS on file, then what you do is as soon as you get the input here, the string, you can convert it to lowercase and then you pass that version to the dictionary axis expression here. That would be something like, you know, W equals w dot Lower. We are updating the W value here, the string that user inputs, and then the W here will be passed as a lowercase, as easy as that. Let me do a quick test. Rain and you get the correct definition of rain. Let's think about more possible values that the user might input. Let me clear the command line, so you see better. Let me call the program again. Weather works fine. But how about instead of putting rain, the user types in an extra in there. The program says the word doesn't exist, which is true. But as a programmer, you want to make your program as more intelligent as you can. In that case, you may want to consider checking for strings that are similar to what the user input. In, you need to check if there is some string that is similar to this word. Instead of saying the word doesn't exist, you want to suggest the user that maybe you meant this word, similarly as you do a search on Google. That's a bit complex, but not that much. I'll show you how to implement that in the next lecture step by step. S there. 106. Calculating the Similarity Between Words: Good. As I mentioned previously in the previous video, now we need to take into consideration when the user mistypes something. Instead of, they enter an extra there or something like that. In that case, you want to let the user know that they typed something wrong there. How do we do that? Well, if you have no idea how to do that, the best practice is to actually do some research on Google because the world of programming is very wide and you don't necessarily need to know every possible workaround or solution to do something. Basically, we need to figure out an algorithm to compare, let's say the arraign with N and the actual word arraign with one N, the end and say whether these are decide whether these are similar or not, but you don't have to reinvent the wheel if someone else has done it already. That's why you need to do some research on the web and see if this is something that if there is a library that exists there or someone a source code that does it, a function or something like that. But usually usually often you find a library for that. If you do some research, you realize that you can do that using a few libraries, and one of them is a standard library and it's called D Flip. By the way, you can get a list of Python standard libraries in this page. Python.org library index dot HTML. This is the link. Here are all the standard libraries that you can import into Python. Let me go here and import Dilip. This is a library to compare text. One of the methods is sequence matcher. It's a long name, so what you can do is say from lip, Import sequence matcher. What it does is sequence matcher. You need to pass none there. None is the value for the argument is junk. The first argument is argument called junk, which means that if you're comparing two blocks of text, in this case, we're just comparing words. If you're comparing two blocks of text and you have some junk there, you have break lines and spaces, then you need to pass here a function that ignores those lines. We don't have that scenario for now, so let's keep it simple. We pass no there for that argument. Then you pass the two strings, you want to compare the word rain with double N against the actual word rain and that will return a sequence matcher object, which is nothing interesting, so you need to apply the ratio method to that to get the actual ratio. This indicates a similarity between these two strings in a scale 0-1. They say that these are quite similar. Now this is about getting the similarity between two strings, but what we need instead is, basically, we have a list, a sequence of strings. We have this keys of dictionary. We have a dictionary with lots of keys and the user passes a word, let's say rage with N and you need to compare that word with all those keys of the dictionary because you cannot compare RN with N with with one N in your program because you don't know that this is actually similar to this. Is the reverse problem, so to say. But Diflip has another feature for that and it's called close matches like that. You need to import that from DlpGClose matches. But I'll consume this feature in the next lecture. See you there. 107. Finding the Best Matches out of a List of Words: So we looked at the sequence matcher class which returns the ratio method of this class. It returns this number, but now we need to see how to get the most similar word out of a list or out of the keys of a dictionary. Let's focus first on is on sequence. A list is a sequence and from the Philip input, you get close matches. Now if you do help, get close matches. You can see the arguments that you can pass to this method. The first one is the word. That will be the word that the user passes, and then you have a sequence of possibilities. Word is a sequence for which close matches are desired typically a string. Typically, this will be a string that you want to compare. Possibilities is a list of sequences or a list of strings you can say, typically is a list of strings. Then you have N equals to three. That will define the number of the matches that you want get close matches method to return. Let's say you pass a list of possibility list with six items and each item has that ratio 1-0 0-1 and this method will return the three most similar matches, the most similar strings to the word passed in here. You can change that argument value if you want, and you have a cutoff. That's the ratio here, by default, this will return only those items that have a ratio of at least 0.6 or greater than that. Under that, the matches will not include. Q to the help and let me try close matches. Let's see what we get. Let's say rain then you have a list in square brackets, of course. Let's say help pyramids and rain. I'll leave the N and the cutoff as they are by default. So in this case, you get rain. The reason you get rain is because rain had a cutoff of greater than 0.6 or similar to that. If you're interested about the cutoff, you can use a sequence match, but we are not interested in the specific value. And so Rain was the only one who satisfied those conditions. We get rain here as a list. We're able to get the close match out of a list, but how do we get the close match out of our dictionary keys? Well, we still have data variable here, which I loaded previously here in this session, I load it from the JSON file. So with data dot keys. There is a method of dictionaries, which is called keys, and with that, you can get a list of all the keys of the dictionary. We're talking about only the keys and all the values of the keys. These are the words and each of them has a value associated with it. Basically, you can check the type of data dot kiss, just to see what it is. It's like a digged kiss object, but it behaves like a list. Any what you could do then is apply the G matches methods. Pass rain there to data dot kiss. Let's see what we get. We got three matches. He got rain. Train and raining. If you pass an end of five, you get more matches there. But it's important to note that the list here is ordered. The very first word is the one with a higher ratio of similarity, we're only interested in that first word. How to get that? Well, you're going to ignore this number since you only want the first word and you can pass zero there because this is a list and the first item has an index of zero, so you get rain for the rain mistyped word. So basically, we have the engine to get the most similar word out of sequence now, and all we have to do is to implement that functionality in our function in here. First, I would just like to let the user know through a message they have input a wrong word. I just want to let the user know so then they can run the program again. Next time, they input a new word for now, but later we'll do something more intelligent. So for now, just think about this, give out a message where you mention your suggestion with the correct word that the user may have had in mind. Let's do that in the next lecture. See you. 108. Finding the Most Similar Word from a Group of Words: Great. The program is going well. I hope you enjoying this. It's not a big program so we don't have lots of code here. But however, this implements quite a lot of aspects of Python. We're loading data in Python into a Python data type, and we have functions, we have conditionals here, we have user inputs and later on, we're also going to implement four loops in this code. We'll talk about that later why we need four loops. We have libraries, we're importing libraries here this is Jason. We also need to import the Diflp library. Which we are currently working on. Let's focus on the flip for now. And the word we have is we pass this string with double and here and we got a set of suggestions. The best matches of the word in out of the keys of our dictionary. But the user may also pass a word that doesn't exist at all and it doesn't have any similar matches there like that. Basically, you have three scenarios. The user enters the exact word like rain and immediately you return data with that particular key, that's the first scenario. The second scenario is when the user enters a word that is very close to one of the words you have in your dictionary, like rain with an extra N. In that case, you want to return the first item of the list that the get close matches generates. The first scenario is when you get an empty list, which means that there is no such word similar to that in your list. We have three scenarios, which means we need to apply three conditionals in the conditional block here. At the moment, we have only two. We need one more which says, did you mean this word, please double check it. For now, we'll just pass a message and also note something. You may also want to pass a higher cutof value there like 0.8. Because sometimes If this is a low 0.5 and you pass some random word, that will suggest you a few words which maybe you don't want. You may want to play around with that. In that case, you get an empty list. I think I'll use a 0.8 value for the cut off when I implement it in the script here. So let's go to our code. The first thing we need to check is if the word is in data and return the value for that word. You may ask, what if you want to check for similarities first and not this? Well, I think the first condition you need to apply is the one that you think will have more occurrences. If you think that most of the users will enter the correct word, then you need to check for that condition first. You don't want the program to go through the conditions that have less probability to happen. So you first want to go through this and then the others are ignored if this returns true. If this doesn't return to true, if it's false, then you want to check for another conditional. When you check for more than two conditions, you need to implement the IF statement for multiple conditionals. Basically, we need to check whether this list is empty or not. If it's not empty, that means we got a match in the dictionary. In that case, we want to suggest that match. We want to mention that match in the message. Which means that if get close. Sorry. Let me import it first. From the lib import, get close matches. ALIF get close matches. The word given in dtaKes like that. This is a list object. That's the same thing as this one here. This is a list object and you want to check whether then length of that list is greater than zero. If it is, you want to return. Message, let's say, did you We use a string format here, percentage. I'll explain what that is. Instead, do you need that instead? After the string, after you have closed codes, is the percentage operator, and here you pass the variable that will replace this formatter inside this string. This will be replaced with whatever variable you pass all the right to this here. In our case, we want to pass get close matches for W and keys and you want to get the first element of that list and put it here. This is to understand it. Let's say we have a variable which has a value of one and you say, Hey, like that, percentage A and the percentage S will be replaced with one. That's the same what we're doing in here. An that's all we have to do. If this evaluates to falls, and this evaluates to false as well, then what that means is we're dealing with an empty list. The user entered a word that didn't have any match in our dictionary that didn't have any similar word in our dictionary. You want to return the word doesn't exist. Let me say the script, go to the terminal. The apper arrow key to call a previously executed command. Python three app one dot py, execute Enter word. Let me start with a Correct word, rain, and you get other definitions for rain. Let me execute again, rain with an extra N. We get this message. Did you mean rain instead? So the percentage a was replaced with the first item of the list return by get close matches. Again, if pass a very random string there, it says the word doesn't exist, please double check it. That's it. However, I still see an issue with this, we still can make the program more user friendly. Problem now is that when the user enters a rain by mistake, what do you say, you just pass a message there saying that, did you mean rain instead? Oh yes, I mean rain, but how can I enter rain? Why do I have to exit the program again? So I'm thinking of a solution where instead of just passing a message here and ending the program, instead of that, you execute another input statement. Another input statement and another input function like this one in here, where you ask the user to enter, let's say, Y if they meant rag or N for no, y for yes, and for no, if they didn't mean rag. I yes, then basically pass, you return the value for the rain word. If they pass no to the input message, then you say sorry if that's not the word that you meant, then we don't know what you have in mind. So we say the word doesn't exist, please double check it. That's what I'm thinking. Yeah, think about this and I'm going to implement it in the next lecture. Talk to you there. 109. Getting Confirmation from the User: Great. As I mentioned previously in the previous video, now we're going to implement an extra user input message into the program. Instead of returning this string, basically what I want to return is an input message. If the program finds out that the user passed a word that has a similar words in a dictionary, then you want to ask the user to enter Y or N. How do you do that? Well, with an input function, of course. Like that. Let's add another message off the list. Enter. Why? Yes. I, yes. Or N I no. Basically, whatever the user enters, you need to process that input that input Y or N, they will be basically stored in a variable but not yet. In this configuration that we have here, nothing will be stored in the variable. It will just be a value on the fly, so you need to store this in a variable. Let's say Y N, so for yes and no, equals to that. So now, either Y or N will be stored in Y and variable. You need to process that variable. YN Eagles to, yes, what do we need to do? If the user meant to say rain, then we return data. Here we need to pass the correct word. The correct word, we get the correct word from this expression. Get close matches will give us the best match and we need to pass that match into the data dictionary, so we get the value the definition for rain we use that match because user agreed that the best match was rain. This will be replaced by rain and the user agreed for that. I hope this is clear. Please ask questions. If this is complicated, I'll be happy to answer you. If yes, then return this. Let me check, execute this intermediate step Sorry, I used the equal operator here, which is an assignment operator, you need to check to use the comparison operator, which is constructed of two equal operators. Save the script again and go ahead, Enter word Rain. Did you mean rain instead? Enter Y if yes or N if no. Let me enter Y. We correctly get the definitions for rain. Great. Maybe I need to improve the message here, delete the dot and use a column there and a space. That should be better. If you pass rain again and if you pass yes or no, you just say N, you get none. Because you are not taking into consideration the N string. You get no because the function is not returning anything. What happened here is use a pass in in here. So word is equal to rain. Word is passed in here. Y is equal to rain then we check if rain in data is not in data because it's with N. This is not executed. The function does not execute this statement, it doesn't return the definition for rain, but it goes to this statement. This finds a similarity so the list is greater than zero, and then it goes and execute this. That's why we got another input message here. Then we continue there. We are indenting under L if we have another nested conditional, which is no problem. But be careful, you need to indent it. This is one level of indentation deeper than this one in here. Here we are. If the user passed, why we return this statement? If the user passes everything else, then you are not counting for that particular scenario. Therefore, there is no return statement executed, so the program will end here and it will return none because nothing was returned. This will also not be executed because this is one level of indentation with this one and since this was executed, the program never goes to this level here. What we need to do is we need to count for other user inputs such as N. In that case, if the user enters N, well, all we can do is return the message word doesn't exist, please double check it, which is the same as this one here. We need to count for another condition. The users may pass N, but they may also pass another random string and you don't want the program to return none, you want the program to return a message. Such as we didn't understand your query. That's it. That's all you can do or your entry, maybe that's better. This is a program. Again, we have a scenario where the user enters rain exactly, and this will be executed in that case, and the scenario when the user enters a word, which does not have any match. ASD CAC C, something like that. In that case, this will not be executed. I got that sit. Let me test the program now. Enter word. Rain. We get the definitions for rain. Again, enter word. Rain, like that. Did you mean rain instead? Enter if yes, enter, no, if no. Let me try yes, and we get the definition correctly. And enter N for no. The word doesn't exist, please double check it. That was good as well. We got this executed. The other scenario would be like that. Instead of entering Y and N, you just type in something and you say we didn't understand your entry. Good. The other scenario is when you enter a word that does not have any match at all, and in that case, this will be executed immediately. And that's it. By the way, even if you enter numbers, let's say one, the word doesn't exist because it's not included in the dictionary. I think our program is quite smart now. It's considering lots of scenarios there and it's quite user friendly, I'd say. However, there is one last thing that we can improve and that's the way that the program displays definitions. When you pass let's say three also has two definitions. Let's pass a word that has one definition. Structure, maybe. Oh, this has three definitions. All right. Pyramid. This also has two definitions. Anyway, you get the idea. I was trying to find a word that has one definition. But basically, what you get with such a word that has one definition is you still get a list, which ends in here, so it doesn't have a comma and it doesn't have any other items. It's a list with one item. When you have a word that has more than one meaning, you get this list with more than one items. And so you don't want to show the user list with brackets like that. The best thing to do to show the user is, if you have one meaning, one definition for the word, you just show this definition, no quotes, no square brackets, just a definition. If you have more than one definition, you only show you show one definition per line. So basically, you have multiple lines with definitions. Yeah, we need to implement that too to say finally that our program is good and can be used by anyone, and the output is easy to read. Think about that. We're going to implement it in the next lecture, SU. 110. Optimising the Final Output +: Great. We have a working program now and we edit every feature that we wanted. The only problem now with the program is that the output is not very user friendly. With that, I mean, let's say yes here. This is the output and you get a list here. It's a Python list. What we want to do instead is we want to show each of these lines in one separate line in the terminal. So that output will be more readable to the human eye. Let's go ahead and do that. How can we implement such a thing? This output now is a list object, which means that the call here, the function call, produces this list object. What can we do is we could maybe iterate through this list object, something like we can store the list object in a variable, output will be assigned this list. Then what you can do is you can save four items in the output list, print out the item. Let's save this and try out. We're going to have an issue here, but one step at a time. Enter Y, Y, and this is what I wanted to have. The first definition, precipitation in the form of liquid water goes in the first line and the second definition to fall from the clouds and drops of water goes to the second line. That's good. However, we should keep in mind that our program does not produce only list, but sometimes it produces strings as well, such as this one in here. No I didn't mean that. Anyway, so this is what you get and you don't want that. This is a message saying that the word doesn't exist. So what the program is doing, what Python is doing is it is iterating through all every type of output that the function generates. A function generates a list, sometimes and sometimes it generates a string. How can we fix that? We have a list and a string. Let's think of difference. How can we discriminate a list from a string? What's the difference between a lis zone and a string? Well, the difference is clearly a data type. A list is a list object and a string is a string object. How about implementing a conditional here? We say something like this if type of output. Is a list, then indent this with four spaces and that one as well. This look now is nested inside the conditional and will be executed only when this evaluates to true, only when we get returned a list from the program. Else, if it's not a list, it has to be a string. In that case, we want to print out the output without iterating through it. Let me check. And we get the output correctly this time the message the word doesn't exist, please double check it. Let's check another time with a correct word and we get the correct definitions in there. Let's try another word. Mathematics. This time, the mathematics word has only one definition, so we get the definition pret out in here. It's a science. Let's try the other scenario as well, rag. Did you mean range? No. The word doesn't exist, please double check it. We got this line here executed. So this is the complete code. I think we can consider our program complete now. That's what I thought of adding to the program. Now the program is quite user friendly and we are considering many scenario there that user may input to the program. However, the interface is still a command line interface, so it's not a desktop graphical program and it's not a web application. The interface is the command line, you send input through the command line and you get output through the command line. What I'm trying to say is that you can actually extend this program so that you can transform it into a web application where the user instead of entering the input through the command line, they can enter input through a web page. Through a live website, they can input, push a button and then get the output dynamically on the HTML web page. That is possible with Python, but you're still not ready to do that because we have quite a few more sections to go. We have some applications where I'll teach you how to develop web applications with Python. And after that, you can go back to this code and extend it and create a web interface. Also, you'll be able to create a desktop graphical user interface with the knowledge that you'll gain through these sections because we're also covering graphical user interfaces in the course. And also we are also covering databases. Why I mentioning databases? Well, because in this program, we're using this file where to store our dataset. The problem with this is that if this gets too big for now, this is just 5 megabytes, that's good. But if the file gets too big, then you need to load the file in Python every time you execute the script. Like here, we are loading the file into the Python session when you execute the script. Now, if the file is too big, that will be very costly in terms of time. What you want to do instead, you want to use a database. Maybe. With the database, what happens is that you make a query to the database and instead of getting the entire dataset, you actually get only that row or that value which you query for. Databases are very efficient and will cover databases later in the course. After a few sections, I'll get back to this program. I'll give it to you as an exercise so that you can extend it by creating an interface, a graphical interface for that or a web interface, and I'll give you access to a database where you can query data for this program so that it becomes a real robust with a very friendly user interface. I hope you like the idea and I hope you're enjoying the course, let's move on with some more sections. I'll see you later by 111. How to fix Syntax Errors in Python: Hey, welcome to this new lecture. This is the most important lecture you have had so far in this course. Please try to make the most of it. This is actually a new video that I'm adding to the course. I didn't have this lecture a few times ago, so I added this quite a while after I published the course. And until now, I had explained this concept, so the errors little by little in other lectures. But I felt that that was not enough and I was seeing that students were still having difficulties in understanding and dealing with errors in Python. I decided to make a dedicated lecture for errors in Python. Here we are. I said, this is the most important lecture because we learn about functions and strings and numbers until now in the previous videos. And these are individual concepts that you learn an hour or later you learn functions and strings, et cetera. But if you don't know how to read an error, how to understand an error and deal with it, if you don't know that, you'll have troubles dealing with everything, every other object like functions and strings and numbers, et cetera. So understanding an error and knowing how to deal with it, how to fix it is very important. And even the most experienced programmers, they make errors in their programs. The difference is that they know how to read these errors, how to understand and fix them. But everyone makes errors. If an error shows in your program, don't panic, just follow the instructions that I'll give you in this video on how to fix the error. That's what this lecture is about. So what is an error anyway? An error in a program is a bug that causes the program to function incorrectly. Now, in Python, we have basically two types of errors. We have syntax errors and we have exceptions. Let's first focus on syntax errors and let's forget about exceptions. We'll go to exceptions after we explain syntax errors. I have this code here and actually, this is a Python file. This is the icon showing on a Mac. Currently, I'm on a Mac computer, but that doesn't make the slightest difference, no matter where you are, Linux, Windows or Mac, everything is the same. I have the terminal here and let me go ahead and execute this program. This has a few errors. Let me show them. On Mac, you can call Python three with the Python three command. On Windows, you can just call Python or whatever command you are using. You can also use any editor that you like Errors dot pi is a name I gave to the script execute. So this is now example of a syntax error. This is the entire body of the error message, and this is very important. Whenever you get an error, the first advice I give you is don't panic. Just focus on the error, read it line by line, just like you're reading a poem or whatever. So the first line of the error points you to the name of a file that has the error. In this case is errors dot pi. Then you have a comma and after the comma, you have the line where the error occurred. It's line three and you can see here that line three is this one here. But you also have for your convenience, Python prints out the line in the terminal. In nine, here is where the error is and after that, you have the type of the error. It's a syntax error. You also have other types of errors such as name error, type error, but those are exceptions, and I'll explain later why we call them exceptions. This is one type of syntax error and the others are exceptions. This is a type and then you have a description after the column. Sometimes the description is more specific, more detailed. This time is just invalid syntax. You have to figure out where you did some error or where you missed some syntax of your program. You also have this arrow here pointing upwards, and the arrow points you either at the token that the error is occurring or at the end of the token. Token is this is a token in this case, nine. It can be a number, it can be a string, anything. At this point, this is pointing at the token. But it could also be like that 999, save the script as a cute in this case, you see that it's pointing you at the end of a token. Here around here you have an arrow now and I know that It is actually a function and functions in Python A need to have brackets, so you need to pass 999 inside brackets like that, and you leave that. Save and execute again. All right. You've got another error, but don't panic again. This is my advice always. Instead, I read the error, it says file errors Line five, line five this time. It's not line three anymore, which means that line three was fixed. What Python is doing is it's going through all the lines one by one from top to bottom. It checks the first line, it says, it's fine. No error there, goes to the next line, no error, goes to the third line, no error this time. Fourth line is also fine. Fifth line has an error. Again, it's a syntax error, and this one is more specifically described. Missing parenthesis in call to print. Note that you get this error only if you are on Python three, if you are on Python two, this won't be an arrow because Python two, print was a statement and was not a function. With statements like return or print in Python two, you don't have to pass brackets. The syntax would be correct. Again, this arrow here is pointing you at the token, we just add brackets there. Control S to save the script and execute again. This time we don't get any error, the script executed fine and printed out the output here, one, two, three. We had three print functions, printing out output. This doesn't return any output because we're not printing anything. This just gets the function input and produces some output, but that doesn't print anything. If you want to print it, you want to pass the print statement function there. There could also be other types of syntax errors such as you want to define these one, two, and three. But instead of closing it with a square bracket, you use a round bracket instead like that, save the script and execute. You see that you got a syntax error invalid syntax at line five, which is this one in here. Again, the arrow points you at the token, so you need to figure out how to fix this round bracket here, and you know that. You need to close it with a square bracket, that should fix the issue. That's about syntax errors. They are very easy to fix. In the next lecture, I'll explain exceptions. I'll see you there. 112. How to Fix Runtime Errors in Python: Hi, again, welcome to this new lecture. In the previous lecture, we talked about errors in general and I focused on syntax errors, which is one of the two types of errors you have in Python. You have syntax errors and you have exceptions. Now we're going to talk about exceptions in Python. Every other type of error that is not a syntax error is an exception. Often all errors, syntax errors and exceptions, they are referred to as errors. So you're going to hear this all over the place. Now I have a new script here that I created for this lecture. Try to guess what I'm going to get as output I execute this script. I have A equals to one, B equals to character two, print in 2.5 and print A plus B. Guess what I'm going to get for a moment. Now let me run the script, Python three, errors dot Pie. File errors that pi, line four, which is the last line. This one, we get a syntax error invalid syntax. Now this can be very confusing for you now because you're looking at the print A plus B expression, but you don't see any arrow there. For a beginner, this can be quite frustrating, but try to look back on the left of the arrow here. Think of the arrow that the arrow is pointing at the token and the token has not been written correctly in the script. In this case, the problem here is that this line here, it has an open bracket, round bracket, and then it has int function, then the int function has its own bracket that is wrapping inside its input. These are the brackets of the in function, but the print function doesn't have a closing bracket. What you did instead, what I did actually. What I did is that instead of putting a bracket there, I actually wrote another print function. Python was expecting a closing around bracket, but I typed in a print function. That's why this is saying that this print function is not in the correct position. That's the idea. Always, when you see this arrow, first look at this line, but then look before that. Sorry about this. Always, when you see this arrow here, first look at this line here, but also don't forget that the problem might also be before this line. That was about the syntax error. I'll explain why I talked about this syntax error here. Let me exec this again. The syntax error was fixed now, but we still have another error. So the reason I included a syntax error in my code was to show you that Python actually first checks for syntax errors. Basically, it parses the code. It looks for syntax errors. It doesn't execute the code yet. When I executed Python three errors dot pi in here, the code was not executed, but the interpreter just checks for syntax errors. It doesn't check for exceptions just yet. First you need to fix the syntax errors, and that's what we did here. We added this bracket and we fix the syntax errors. Now Python is throwing out an exception. And let's here is where I executed the code and see the next line, we have number two there, which is coming from the output of this line here. From line three, we got the output correctly. Basically, again Python execute a script from top to bottom. If it doesn't find syntax errors, if it finds syntax errors, it doesn't execute anything. To is printed out, and then you get this trace back of the error. Which starts there and ends in here. That's a block of the error. Sometimes the errors may have more than one type of error. In this case, we have only one type of error, which is a type error, but you may have multiple blocks here. However, the most important error that you must focus on is the last line of the error, the last block of the error. In this case, we have only one block, we're focused on in that. Line four which is this one in here. This is a line. Again, the line is printing out just like in the case of syntax error. Here you have a type of the error here, which is a type error. What's a type error? A type error means that there is something wrong with one of your object types in your script. You have the description here. I supported operand type four plus. So this is trying to say that the plus operator has an unsupported type, the plus operator, in other words, doesn't support one of the types that you have given to it, it either the type of variable A or the type of variable B. It says Int and string. It doesn't specifically say that whether Int or string is object, but it says that you cannot use a plus operator with an integer and a string that's logically wrong because you cannot add a number to some text. That's what Python doesn't understand and it throws a type error. Exceptions are logical errors and you need to use your logic now to fix the error and use our logic by carefully inspecting the error, and that's what we did. What we want to do we want to fix this. Now it's up to me whether I meant to concatenate these two objects or do a mathematical addition operation. Let's say if I was intending to do an addition between these two numbers, then I would have to convert B to float or an integer. Say that. Execute. A, this case you don't get any error, you get two printed out from the third line and 3.0 from the last line that we have just fixed. However, if my intention was to actually print out the concatenation between these two strings, instead of converting B to a flow, I would have to convert A to a string. In this case, I'll get the text one and two, one and two. That would be a string object, not a number. Even though here shows as a number, it's just how the terminal prints it out. Again, these are errors that occur in runtime, so the script executes. Syntax errors are parsing errors, so the interpreter tries to understand whether the script is syntactically correct, whether you are full, whether you have followed the Python syntax rules. You need bracket, closing bracket for opening bracket. You need a closing quote after the opening quote and so on. Now there are also other types of exceptions. Not only type error, you may have a name error. Let's say here instead of printing out that we print out C, save, execute. Here is a traceback. Again, two was printed out from the third line. The traceback says line four at print C. Name error name C is not defined. Again, this is not a syntax error because you haven't made any mistakes with a syntax. You have this variable name which is correct. You have brackets opening round brackets and closing around bracket. Everything is syntactically correct, but this C object, Python doesn't know this. You haven't defined this C variable, Python doesn't know what to printout. Python is able to print out A because it knows that A refers to to integer one and so it prints out integer one, but C doesn't have anything. You get this name error. And whenever you get your name error, you know that this name here has not been defined by you. To fix this, you may want to define C like that and execute and you don't get any error. You may also have other types of errors such as C divided by zero, see what you get. Zero division error, division by zero. That's the description of this error. Division by zero is not mathematically possible or meaningful. Since Python is based on mathematics, then it throws an error and you need to fix that, you need to remove that expression that divides by zero. Anyhow, that's about errors in Python, I hope you understood a great deal of this lecture and the previous lecture as well. It's relatively easy to fix errors, however, sometimes there are errors that you might have difficulties understanding and fixing them. Later, for example, we're going to work on libraries and sometimes libraries, they have different kinds of errors. However, nothing to worry about because there are other things that you can do for an error that you don't understand. I'll talk about that in the next lecture. I'll see you there, see. 113. How to Fix Difficult Errors: Great. Welcome again to this new video. This is the third video about errors. We talked about syntax errors, we talked about exceptions, and now we're going to talk about how to fix an error when you don't understand the message. Let's focus on this error. A zero division error. In case you were good in mathematics, you could easily fix these errors. You'll be able to understand that you cannot divide you cannot divide a number by zero. You would fix this by removing this expression here. However, if you were not that good in mathematics, you may find this difficult to understand. In that case, the fastest way to fix this error is by copying this line here, Control C. Select it, copy it with Control C or right click and copy there, and then go to Google. Just paste it. Now, on Google, these got around 100,000 results. Python is very popular and you'll get a solution for almost every problem that you get with Python. Before looking at documentation or asking a question somewhere, it's very likely that someone else has had your issue before they have asked a question about that and there is a solution about that as well. A very good question and answer website is stock overflow.com. Almost always when you search for an error on Google, the first results will be from suck overflow. Someone has asked a question with this title. I face an error when I run the program using Python. It's the same exact error as you like that. How to avoid that error. It also talks about the desired output. There are two answers for this question. The answer with this green mark here is accepted answer and it has the most up votes. 11 and this has two down votes, minus two. Actually, the difference between up votes and down votes is in favor of down votes. These are two different answers that you can look at. Usually, you want to look at the accepted answer that has the solution. However, in this case, this also has the explanation. It says you cannot divide by zero. This causes Python to raise an error. That's still a good answer, and I think it didn't deserve to have this balance of votes. But this one gives a solution on how to handle an error that takes us to another concept which is handling errors in Python. Let's say you have a program, you have a function that gets two input values and then it divides those two input values. However, sometimes user may pass zero as a second input. In that case, if you divide, let's say, the first value would be two and the second value would be zero, your program would crash and if you want, you can use exception handling to actually avoid that program from crashing. You can do that with try and accept statements. Anyway, we'll cover that in the next lectures in this section. This was about searching for an error on Google and you can easily find the solution to that. As you see. These are very clear questions. It's a big community and everyone can vote up and down and can comment. Basically, the answers are very accurate. However, you not always find an answer on Google. In that case, it's time to ask your own question. The first thing is, again, you check if you understand the error and fix it if you understand it. The second thing is you do a search on Google and if the first two fail to solve your problem, then it's time to ask a question. You can ask a question either inside the course. While watching a video, you can browse Q&A, which stands for question and answer, and you can do a quick search if you find an existing answer to your question here, and if you cannot find it, then you can ask a question or you can ask a question on Stock overflow. You can use this button here, ask question and I'll be happy to help you here on the course interface, Q&A section, or other people can also help you on Stock overflow. However, something is very important to know. The structure of your question is very important on getting a good answer. Sometimes there are very bad questions like, let's say, my code is not working, how do I fix this? That's all. With that very little information, it's very hard to get a good answer. It's very important to ask a good question and I'll show you how to ask a good programming question in the next lecture. That's a very important lecture as well. See there. 114. How to Ask a Good Programming Question: Hey, hi, Again and welcome to yet another lecture. In this lecture, I'll show you how to ask a good programming question. As I mentioned in the previous lecture, asking a good programming question is very important to get a good answer. Let me first show you what's a bed programming question. For instance, I'm going to click on Ask Question and here is the title of the question. A Bt programming question would have a very generic title like that. Here is the body of the question where you have to describe your question in detail. Some people, they just say, I got an error when trying to two numbers. I just pause the question. A better question would be to include the code there that you executed like that. However, that is also not enough because you also need to show the error message. Let me delete this and a good programming question would be when you're talking about questions that have an error, questions that talk about an error that you got in your code. This is your code. A good title would be to include the error message. That one would be a good fit. If it's a very long message, then you can choose to include only the name of the error with all that. And then a good question would be, hi. I ran the following code and expected to get division in the last print main but I got an error. Here is my code. So you put the code there, the entire script. Don't worry if your question is long, it's better to be long than to be incomplete. Here is the error. Here, make sure to include your entire error traceback including the output as well. From this line of the command line up to the next line. This entire thing goes to your question. Just copy it. Don't worry if it's long. Can you help? That would be a good programming question. Now, this is still missing something very important, and that is the highlighting of the code. You need to select the code and click on this icon here. The error as well. Let me pose the question. External links must provide free educational content, just click on proceed. Here's a question here is it looks like on the other end. This question has four good elements that make it a good question. The first element is that the poster is mentioning what he or she expected to get as output from the script that they were running. So it says that I was expecting to get the division in the last print statement, which is this one here, but I got an error. The first thing is you need to include the expected output. You need to explain what you were expecting because otherwise, if you don't explain what you are expecting the other person who wants to help you doesn't know the goal of your code or of your question, so it doesn't know how to help you to reach to that goal. Expect output is the first thing. Second thing is you need to include your entire code. And make sure that you include your code as text. It's better to use text as screens rather than screenshots because text, the person who wants to help you can copy your code and run it on their Python interpreter. But if you include screenshots, they are images and it's hard for other people to try out your code. If you ask this on stack overflow, your question would get closed because if you ask it using a screenshot rather than the text version of your code, the question would get close because there are very strong rules in stack overflow to have a high quality question and answer side. That's the second element. The third element is you need to include your entire screen entire error traceback, sorry. From the beginning up to the end, that was the third element and the last element, the fourth element is you need to highlight your code. Just like that, you see this is much more visible and easier for others to troubleshoot. The course interface has that function there that you can highlight your code. On stock overflow, you also have that capability, just go to ask question, write your career and highlight it and then use this curly bracket. Yeah, that's it. If you ask good questions, the odds are that you're going to get a good answer as well. I hope this makes sense and I hope I showed you something that you didn't know and I'll talk to you later. See you. 115. Making the Code Handle Errors by Itself: Hi, again. Let's have one more lecture about errors in Python. This particular lecture will be about handling errors. Handling errors can be an advanced concept to digest for now because you're still going through the basics of Python and you haven't seen any real application yet. But later we will use error handling when we're building real world applications. So you're going to understand error handling better later on. For now, let's just focus on the syntax and try to understand as much as you can. I'll go and do an example here, which I mentioned earlier, let's say we have a function that does division between two given numbers like that. Return A divided by B. Then you call the function. Divide one, two. In this case, the function will try to divide one by two. Let me print out the output so that we can see it on the terminal. Go to the terminal and execute the script, you get 0.5. Now, that's good. However, if the user enters, let's say, zero there like that, execute and your program will crash, so it will show an error. Now, this one here is an example of a longer error message that I mentioned previously in the previous videos that you might have more than one error in your trace back. For instance, this says file line four this line here. That line is where Python captured the error at first. Basically, Python was trying to execute this line, but it couldn't do it. It didn't manage to do it because this line was trying to get the information from this function and this function was trying to do this mathematical operation using zero after the division. So that is not possible and Python is pointing that out here. That's the main error in line in this expression. That's where you should focus. However, when you ask questions, you should include the entire error message in your question as I mentioned previously. Back to handling errors now, what I'm trying to say here is that if you have other functions here and other lines of code that you want to execute that you want Python to execute. But if the user passed this zero number here, the other lines would not be executed. Your program would crash and you don't want that. The way to avoid that is by using try and accept. Basically, you try to capture the exception. To handle the exception. The way to do that is quite easy. Try, you say try and return A B. This has to be indented like that. Try is indented because it's under the function definition, and then return is indented because it's under the tri expression. Then you have except execute. This has to be in the same indentation level with tr. They are the same block. Except if there is an exception, what you want to do is prio you are dividing by zero or is meaningless. Let me try this now. And you get zero division is meaningless. Sorry, I meant to do here return, not print. I explain you why you get none there. You got none as an output because what the function did was it tried to do this expression, but it got error, so it ignores this line, it doesn't execute it, and then it goes to the next line. This line is executed when this is not executed. And so it printed out zero division is meaningless, but it also printed out none because when you execute a function that doesn't have a return statement, such as in this case, we had a print statement here, print function, not a return statement. In that case, if the function is not returning anything, it can have a print function or other function as well. But if it doesn't have a return statement, then it will print out none. Basically, it executes the other procedures such as the print statement, it prints out the statement. But if it doesn't have a return statement, does it prints out none. Anyway, say this execute again and in this case, you get only this zero division is meaningless printed out there. Basically, if you had other lines of code here, like that, those would be executed as well. That happens by using the try and accept block, which makes sure that the code flow continues. One other important thing to note is that it is advisable to actually here use the exact name of the error that you want to accept. So zero division error. As you see this got turned into blue, which means that this is actually a Python keyword is recognized by Python. In that case, if you execute this, you get the same output actually like that. Or if you pass a number there that it is possible to get a division from, you'll get that. Sorry about backslash. I typed that by mistake on my internal execute again, so you get this. What I'm trying to say about zero division error is that sometimes you might get other types of errors in your code. Other types exceptions. Let's say you have a name error there and you are saying that except all errors when you don't pass this, you're basically including all types of errors there. That is a bit dangerous for your code because you might have problems that you don't notice and basically you are ignoring them, but you shouldn't. You should be specific there explicit like that. If there are other types of errors such as a name error, that name error will crash your program you know what's going on and you need to be specific. If you want to handle that error too, then you can add another exception here except name error for instance. Yeah, that's about handling errors in Python. I hope this makes sense. I hope I explain this well this about errors. I'll talk to you in the next lectures to you. 116. Introduction to Computer Vision with Python +: Hey, welcome to this new section. And throughout the lectures of this section, you are going to learn computer vision with Python. I'll explain computer vision in a minute. So that's what we're going to learn in this section. And then in the next section, we'll build an application that detects moving objects from the computer webcam and stores and visualizes the times when the objects entered and exited the video frame. So that's an application area of computer vision. Now, maybe you have an idea of what computer vision is, but if not, I'll explain it now. So computer vision is the field that deals with acquiring and processing images, and it makes decisions based on them or the images. So you pass an image to the computer, and the computer tries to understand it and it can do certain things such as it can tell you how many phases there are in the image and what color dominates the image, and so on. I know, computers are dump. I mean, you have to tell them what to do exactly. And that's where Python comes in. We'll use Python to load images and process them and do things like face and motion detection. Now, vision includes both images and videos because videos are simply stacks of images that show very fast. So computers and therefore, Python use the same commands to read images and videos. And you can do computer vision with Python using OpenCV. OpenCV stands for open source computer vision. And Ise library use not only in Python but in other programming languages as well to do computer vision tasks. So in this section, I'll introduce you to OpenCV and you will learn how to use it by detecting faces from images. Then in the next section, we'll dive deeper and process videos with OpenCV and detect some moving objects in real time webcam video. So, yeah, that's about this lecture, and let's move on and quickly set up OpenCV in the next lecture, then work with it after that. So yeah, thanks and see you in the next lecture. 117. Loading, Displaying, Resizing, and Creating Image ++s with OpenCV: Great. So let's go ahead and play around with OpenCV a little bit. Specifically, what you learn in this lecture is you learn how to load images in Python using OpenCV, and you learn how to display them, resize, and then save the resize images in new image files. So load, display, resize and write images. And I've got a nice image of galaxy so I'll play around with this. The first thing you want to do is import the library. The second thing is you want to load the image in Python. So image would be equal to cv two dot image REIT method. So the method expects now the path to the image that you want to load in Python. And that would be galaxy dot JPG. So my script, one dot Pi file is in the same director with Galaxy dot JPG. So I just need to pass the file name here. And then there is yet another parameter for image for him at method. And then this parameter takes three arguments. Now, this parameter specifies how you want to read the image in Python. So do you want to read it as an RBG image, which means do you want three bands in your image? So you want a color image with a red band, blue and green band. So if you want to read the image as it is with colors, you'd want to pass one here. If you want to read the image as black and white image in a gray scale, you'd want to pass zero. And having a grayscale image implies that your image will have one band. And I'll get back to bands and explain them in just a moment. So we also have minus one. This means a color image, but you also have an Alpha channel, which means your image will have transparency capabilities. So if you apply operations that require transparency, you can do that read when you load the image with a minus one argument here. Okay, so I'd like to try out zero. Great. Now, before I show the image, before I display the image on screen, I'd like you to understand what this image object is about. So I'd want to print the type of it, just like that. Execute the script. Script one. Yeah. Of course, and try again. So this is numPiN dimensional array. And if you want, you can print that out. And you'll see the actual num pi array. So this is a two dimensional array with values in the horizontal axis and in the vertical axis as well. So think of the image now, and this would be the very first, so the top left intensity value of a first pixel. So 14, for example, would be the intensity value in the gray scale. For the first pixel of the image, so for the top left pixel of the image. And then the second pixel and so on, and then you have these dots, which means Python cannot display list, the long list in here because you have a couple of thousand values in the first row, and then you have the second row of pixels in the image and the third and so on. And this makes the matrix of the pixels of the image. And if you want to know how many numbers, how many values you have in the horizontal direction and how many values you have in the vertical directions, you can go ahead and print image shape. Okay. So let's say that the image resolution is 14 85 by 990. So Python stores the image as an umpire array as a matrix of numbers as easy as that. If you want to check the dimensionals array of your image, you can do that with this expression. And you see that you have two dimensions. Now, if this was a color image, so with three bats red, blue and green, things will change a little bit. So you've got three dimensions. And you also see that the new array is a bit different. So here you've got values for each of the bands for green, for red to green and blue. So I'd like to stick with the gray image. And what I can do now is I can display the image on the screen. And for that, you want to use the image, so I'm show method. And this will display a window and you want to name that window, so you want to put a title for that window. Let's say galaxy. And what you pass here is the image object. So this one. Great. And then what you want to do is you want to specify a time for your window to be closed because this will show the window, but you also want to define some functionalities so that the user can close the window. If you put zero here, when the user presses any button, the window will close. Let me change this to Cb two. So if you put zero, the user can close the window pressing any button. If you want to put a time, you could say 2000 and that implies 2000 milliseconds. So that means 2 seconds. So we said how the user wants to close the window, and then you want to specify what to do when the user presses a button or waits for 2 seconds. So you want to destroy all windows. That's a method that closes the window. Good. Let's see what will happen. Okay, so we got the image displayed, and it waited for two sagas, and then it closed. If you put it at zero, the image will stay there. And if you press the button, it will close. Let me show the image again. Now, the reason that you don't see the image fit on my screen is that the image, as you see here in these values is 1485 pixels high. So the height, this is the height, and it's 990 pixels wide. So my screen resolution is set at 1,280 by 720. So that means this image with this size doesn't fit on my screen because my screen is too small for this. So in this case, let me close this. What you can do is you want to resize the image and then show the recise image. So we load the image and before showing it before passing it to the I'm show method, you want to say, let's say, resize. Image. That would be equal to. CV two does resize, and this would get two parameters. The first is, of course, is image object that you want to resize. So IMG is our variable, and then you want to specify a tuple with the new dimensions, I would say 1,000 by 500. And then you want to pass the new image here. So what's happening here is that Python is actually resizing the num Pi array. So it will take the array with this number of pixel number of values, and it will create an array with these new dimensions. So what will happen there is that Python will interpolate those values. So it has quite a lot of values here, but then it goes from this to this. So when it sees, let's say, it has four for one value and then six for the neighbor value. And what Python will do is that it will get four and six, basically, and it will just make a value out of it. So let's say five. That's basically the idea. So it interpolates the values, and then it shows the interpolated image on the screen. Which looks pretty nice in our eyes. Okay, let's see this. And this is the image. And you see that this is quite stretched a little bit. So it was a tall image, but now it's quite wide. And because this is actually the width of the image and this is the height. So if you want, you can say 501,000. So again, and now you see more or less the two ratio of the image. But if you want to keep the ratio of the image, you'd want to go more advanced here. So let's say from this, let's say we would want to show a size that is half of this so that would keep the ratio of the image. So what we can do is we need access to these values. And we can grab those values from shape method. So this produces a tople with these two values, and then we go here and say, image, shape. And this would be this value, so 990, which has an index of one. And then we have, again, image and shape with index of zero for this number. And then we want to divide this by two. Okay. And I expect to get an error from this, but what's S. So yeah, we've got an error. It's a type error integer argument expected got float. But here, what we're doing here is that when we divide this number by two, we will get a float. So we would get something like 742.5. In that case, what we want to do is convert this to an integer. So 742.5 becomes 742. Okay. And let's keep the consistency so integers for this as well. Let's see. We've got an invalid syntax here, so it points us to line 11, somewhere in the beginning, which can be quite misleading. So you want to see before that line, which is here. And you can see that this bracket here closes here. So we need another bracket, which closes in the first bracket here. So save that. Try again. And this time, the image looks good. So you learn how to load an image in Python, and you learn how to resize an image, how to show an image on the screen. And now let's go ahead and write the resize image in a new file. For that, you'd want to use the IM write method. So image shte. And you want to give a name to the new image, Galaxy, let's say, resized dot JPG. And then you pass image object that you want to store in this file. So the comma goes salts here, and the image you want to store is precised image. That's it. Execute. And we got the old image resize on the fly. So Python gets the numpy array. I interplates it, so it resizes it, and then it shows it on the screen. So this is Galaxy, this one here, and then we can close this. And here we've got our new image. So galaxy resize. So if you go to the folder where these files are, you'll see that this image has new dimensions. So 495 by 742. And that's what I wanted to teach you in this lecture. Hope you enjoyed it and talk to you later. 118. Explanation of Previous Exercise: Well, I hope you solve the exercise, and I believe it was not a difficult one. My purpose there was to get you used with OpenCV code. A why not to practice a for loop? So as you can imagine, this exercise would be sold by using a for loop. So let me go through the code line by line quickly. So we have two important OpenCV, SL CV two, and the globe library. Now, if you can recall it, what Globe does is that it finds the path names of some files given a certain pattern. So in this case, for instance, I have these JPG files here, so one, two, three, four, five images. And I said, Okay, create a list of file names that contain everything in the first part and then JPG as extension. So that will create a list such as say, C and then the path here and then Galax C, the GPG. And then the other image path and so on, you get the idea. And then what we need to do is iterate through this list for each image path in the list in this list. We'll do these operations for each of the list items. So first, we read that image path. Okay, that image file actually has a black and white image. So zero is a flag is argument, which implies an image rate as black and white in the gray scale, actually. Then we create a variable where we will store the resize images. So the image is 100 by 100. I'm passing the original image here and the size, the new size that the image will get. Then we want to show the image just for demonstration. This is not really important, but it lets you check out the images that are being resized. And this is the name of the window. And then I pass here a wet key method, and 500 means 500 milliseconds. So each image will show and it will wait for half a second, 500 milliseconds. And then after this half a second, Python will go to the next line and then to the next and then it will go to the next item of the list and so on. So wait key 500 milliseconds, and then we have destroy all windows after this time passes. And then we write the resized image. So RE was a variable that holds the image object, the resized image object. And this here, all the is a new name of the file. So what we get here is so we will have recise in the beginning of the image name. And then just after that, we will have a name of the original image. So for instance, we would have for Galaxy, would have reciseGalaxy dot JPG. So image here would be galaxy dot JPG here, which is this one here. And here, because the script is inside this folder, this list, actually, the image is would look something like Galaxy dot JPG, then Kangaroos, you know, Australia, dot GBG and so on. So this gets the relative paths of the files. We're not getting the full path. Okay, I hope that is clear. So resized Galaxy, we could add an underscore so that we discriminate the recise word from the other image name. Great. Let me execute this Python script. So alpha second, Alpha second, and, yeah, it's done. And let's check the images. So from here up are the original images, and these are the image products. So you can see here that all these are 100 by 100. And they are in a gray scale. Okay, that's it. See you in the next lecture. 119. Detecting Faces in Images with OpenCv and Python: Hey, welcome to this new lecture. And here you learn how to detect faces. And we'll be using OpenCV with Python to detect one or more faces from an image. So basically, how does face detection work anyway? Well, the idea is that someone has created some cascades, which are basically some XML files such as this one. This EML file contains information about the features that an image of a face contains. So we're talking about ratio of the shadows of the eyes and nose and lips and all these features, these pixel intensity numbers are stored are recorded in this XML file, which has been created by using some images with faces as training samples. So basically, you tell your computers, Okay, all these are faces, and then you use software like OpenCV to create such XML files. So these are called hard cascades, and this is a hard cascade for a frontal face object. And if you want other objects, you can find them in this link here. So you've got full body, left eye, and lower body and so on. Alternatively, you can use a resource section of this lecture. You can download on a Zip file with all the XML hard cascades there. But in this lecture, we'll be focusing on front of face. So we'll be using this cascade to detect pass. The way it works now is that we will load the image in Python, and then we will tell Python that this is a model that you want to look for in the image and you want to find this model, so the XML model in the image. And what Python will do with the help of OpenCV, it will start to search all the image using a window. And then it will resize the image, it will decrease the image size, and using the same window, it will detect for smaller pass and so on. We'll go through that step by step. So let's write the script that detects faces. Impulsivity is the first thing you want to do. And then the next thing is you want to read the cascade in Python. So let's call the variable phase cascade. CV two, and we have a method called cascade classifier. So this will create a phase cascade object in Python, and all we have to pass here is the path of the heart cascade. That's it. And that will create a cascade classifier object. And now you can use this cascade classifier object of the pace feature to search for a phase in your image. So the next thing you might want to do is to load the image in Python, the image that you want to search for face. Let's say image equals. So you know that we can load images in Python via the image read method of the open CV, and you can just pass the photo dig PG name here. I'm passing the file path of this image. So I'm not passing any second parameter here. That means I'm reading the image as a color image. However, a good idea is to use grayscale images when searching for a face. So I loaded the image here, but I'll be using the grayscale version of the image when searching for a face in that image. That is thought to produce higher accuracy when searching for faces, because you may notice that when you have very busy images with lots of features, OpenCV will not be 100% accurate. So you may get faces that OpenCV will miss out, or you may get features that will be classified as faces. Using the grayscale image though increases accuracy. I could go ahead and pass a zero flag here so that I could read this image as a gray scale, but I'd like to actually keep the original image as a color version because I want to show the color version at the end, but use the gray image. Pass it to the methods that we'll be searching for the face. So I'll create here a gray image variable where I'll sort the gray scale version of the image. So CV two, and we have a method called CVT color, and that takes as argument, the original image, of course, and a flag. So an argument. Called Cv two color BGR two gray. So what this means is that this will convert the BGR image, so blue, green, red bands, it will convert it to a gray scale image. Let's see. So if you want to quickly show this gray image, if you like, Civ two show gray image there. We give a name for the window, gray and the image you want to show, then you need to pass the weight key parameter here. Let's say zero, so we'll press Aiki and it will close the window. CV two destroy all windows. So you learn these methods in the previous lectures. Let me execute this. So this is a gray scale version of the image. Come. Now we will use a method called detect multi scale. And what this method will do it will search for the cascade classifier. So it will search for this frontal face XML file in our image, and it will return the coordinates of the pace in the image. So for instance, this is the image, and what this method will return is, it will find the face and it will say. So it will give you the number of the row and the column of the upper left point of the face. So it will start here and it will also give you the height of the face and the width of the face. So we get a rectangle. And then we will draw that rectangle in the image. So that's basically, but you'll understand it better. And so we need to create, let's say, a pass object variable. Where will store this X, Y, width and height values. So let's quickly grab that. So we need to refer to the cascade classifier object, which is this one here. And what we want to do with this object is detect Mul ti scale, and you want to detect the gray image. And then you want to pass scale factor in there. You know that when you have lots of parameters and there are too many to fit in a line, after the coma, you can just press Enter and Python will read your line as it was one single line. So they'll be sure to just press Enter after the coma. And so we have scale factor. And a good value to give for this would be 0.5. Now, what does this mean? Anyway? Well, let's consider this image. What Python will do is that it will start from the original size of the image, and it will search I will create a window that will search for faces in the image. So search in this area in this area in this area. And so once it does that, then by giving a scale factor of 1.05, you're telling Python to decrease the scale by 5% for the next phase search. So what Python will do is it will downscale the image by 5%. And it will research for bigger faces in the image. So search again, search again, and then decrease it by 5% again the image and search for bigger faces, and so on until it goes to a final size. So that means a smaller value means higher accuracy. If you give, for example, 0.5 Pythond decrease the scale by 50%. So it will start from the original size, and then it will go 50% higher and so you don't get much accuracy with that. The profit with this number is the script will run quicker. So you'll have less passes to the image searching for a face. 0.5 is good. Okay. And then you have another parameter called minimum neighbors. That is usually set to five. And what this basically is is that this tells Python how many neighbors to search around the window. So you may want to experiment with these numbers a little bit and see which gets the better results. But these two are well accepted numbers. So let's do something now. Let's print out faces and see what this is about. So what kind of object this is. And I could also print the type of faces, just like that. So I'll run the script now and what the script will do it will read this XML file and it will load the image, it will make the grayscale version of the image. And then it will detect the coordinates of the upper left corner of the face in the image and the width and the height of the rectangle defining the face in the image. And then it will print out the type of the faces and it will print the faces, the actual faces object. So press kit to exit this. And so pace is a numPi array, N dimensional array object. And it is an array with four values. So we have detected our face these are values basically defining the phase in the image. So basically what we have here is, so this is 155, which should be the 155th column. So this is the X. So the rectangle should start somewhere here in the forehead. And this should be 83. So the row 83, column 155, and then we have the width, which is 382 and the height, which is the same. And so we have a rectangle in the face. Now, let's go ahead and draw that rectangle in the face in the image. So we created the faces array. And then what we want to do is access all these values of this array. To do that, we can use a four loop. So four X, Y, width and height in faces. Well, image. So we are updating the image object that we have read here, we have loaded here, so we'll update it by drawing a rectangle in the image. And again, you need to pass the image object in here, and then you need to pass four more arguments. The first argument would be the starting point of the rectangle. So that would be X and Y. So these coordinates of the phase array. Great. And then the next parameter is another tuple defining the coordinates of the other corner of the image. So we've got the top left corner in here, and we got the lowest right corner down here. So what that would be is X plus the width. And Y plus the height. That's it. Yet another parameter. This would be the color that you want to give to this rectangle. So that comes as a BGR format. So you want to pass value for the blue color. So let's say zero for blue, and let's have a green rectangle. 255 for green. So we'll have a full green there, and then zero for red. You can also pass another parameter, which would be the width of the rectangle. Let's say three. Okay. And once you do that, so once you have updated your image, you may want to show your image window on the screen now. So we use image show method, but here we have a gray image, so we want to pass updated image object. And we should be good to go. Save the script, go and try to run it. And my system is not being able to find the face atx it dot py. Yeah, I have messed up something with a name here, so let me change this dot py, Enter. So nothing to do with the script. And let me try again. Great. So I hope this is what you were expecting. So the rectangle starts here and it has a width and a height, and it ends up in here. Sometimes, though, as you might already know, you may have images that are bigger than your screen resolution. In that case, your image would not fit in your screen on your screen. So what you could do is resize the image before showing it. So let me create a resized variable here, and that would be equal to cv two resize, and you want to pass image, which contains the rectangle there, and you want to resize the image to these two values. So you need to set the resolution of the image here. And as you know, you can just put some values here, let's say, 500 by 500. But these values might stretch out your image, so a better solution would be to access the shape of the image. Or the resolution of the image, and this should be the width of your image. So you already know this. I explain this. So I'm just going through this quickly, and to make sure you get a good size, you could divide it by three. And then again, in shape, you get the height, which is the first value of the tuple and divide it by three again. And you also want to convert these two integers because you might get float numbers, and Python will say that it cannot resize an image to float numbers. So that should be okay. Then you want to show the resized image. Quickly testing it. I'm missing bracket here, so this should be a topple all of this, but here I'm not starting it as a topple. So bracket here and closes in here. That should work now. Yeah. So, this was my picture, but let's try a more challenging picture now. This one here. So we've got two faces which are not very clear. This is not a real frontal phase. This guy here, he has his eyes closed and his chin is not visible. And we've also got these two faces here in the newspapers, which let me open the original image from here, which have basically very low resolution, and I think Python will not be able to detect these two faces. So let me check this. Here's our face detector, and we want to pass the name of the new image file. Save the script and go ahead and run it. So we've got some back to reality here. And as you see this time, Python and OpenCV were able to detect this phase, even though it's not in a very frontal position. And obviously, it was also able to detect the hand of this guy. So Python reads it as a phase. And what you can do in this case is to tweak these values here, so scale factor and the minimum neighbors. Something you may also be interested to know is the phases array here has two lists in this case. So this is the first phase, the coordinates of the first phase, and then the second phase. Which in this case, happens to be hand, but anyway, you get the idea. So probably by maybe using a 1.1 scale, you may be able to get rid of that hand. So yeah, that's it. You can also try out to detect the pace of this guy, but I don't think you'll be able to do it. So just that you know that these techniques have limitations. So it's a computer. It's not a human being, so it will always have some downsides in the accuracy. I hope you found this so low, and I'll see you in the next lecture. 120. Capturing Video with OpenCv and Python: Hey, welcome to this new lecture. And in this lecture, we will be using OpenCV to capture video from the computer webcam. So you'll need OpenCV and you will import it as CV two, as you already know. OpenCV is what we use for image processing, and, of course, video processing because video is made of images. So we have lots of images and they are referred to as frames. And these frames, these images are showing one after the other in high speed, and then we can see those images as video. And you'll either hate this lecture or love it. What we'll be doing is that we will go in a really low level of image processing here of video processing. We will be reading frames one by one, so images one by one. And you'll see that how we use loops in Python to show those images and to actually build a window where images are showing fast, and you can see it as a video. So if you have a laptop, you probably have a building camera. If you have a desktop without a camera, you'll need external camera to follow me in this lecture. And now, the first thing you may want to do is to read a video. Then once you read a video, so you can read a video either from the webcam or from a video file. And once you read the video, then you can apply other operations such as graying out the video or adding text to the video or detecting objects in the video, et cetera. So the first thing you want to do is to create an object, let's say, video, and that will be equal to cv dot Video capture. So that's the method that triggers a video capture object. And that gets an argument here, which can be either a number such as zero, one, two, three, or the video file path. So when you put a number, that implies that you're capturing video from a camera. So let's say, I have a built in camera in my computer, but also have an external camera. In that case, one of my cameras will have an index of zero, the other camera will have an index of one, and if I have a third camera, it will have an index of two and so on. So that's it. If you had a video file, you could just say movie dot mp four or something like that. It depends on your video file name, and you'd have to have this file somewhere in your computer. But in this lecture, we are talking about capturing video from the webcam. So I have only one webcam in my computer, so I'll pass zero here. That's it. Once you do that, you want to make sure that you will release. The camera. So you want to access your object, Video dot release is the method. And then you don't need to pass any arguments there. So let's see what we have if we execute this. This Python file. Python, capture dot pi is the name of my file. And obviously, nothing happens. But on my side, I noticed that my camera was turned on for a second or for a fraction of a second. So the light of the camera was turned on and then it was closed. It was turned off immediately. So what happens is that we actually trigger the camera here, the webcam, but then we immediately release the camera. So what Python will do is it will open the camera and in a millisecond or so it will release the camera. Let me try it again. Sometimes it might happen that you don't even see a light at all. So you don't see it because the process happens very fast. So probably your computer needs some seconds to actually turn on the light off your camera. And we can give it some seconds, so. To do that, you want to import the built in time library. The time library provides some operations related to time. And so, for example, in our case, we will use it to hold the script for 3 seconds. So what this will do is that Python will try to execute the script line by line, so it will import CV two on time, and then it will trigger the camera. And then before releasing the camera, we will have the script wait for 3 seconds. So this will be executed. Wait for 3 seconds, and then execute the other method. That's it. Now, let me execute this again. Okay, the light is on. One, two, three, off. Yep. And the video is released. Now, maybe you're thinking, why don't we see your face there showing up in the video camera in the window? Well, the reason is that, do you see any line here that I'm showing a window? No. So why do you expect my face to show there? And the way we do that is by first creating a frame object, which will read the images of this video capture object. And let me do that first before going into more explanations. So let me say check frame. That would be equal to video dot RED, just like that. So what we're reading here is we have a Boolean data type here and an umpire array. So let me print this out so that you understand better. So check first and then print frame. Okay? Execute the script. Wait for 3 seconds and close it. So what we got here is, I'll expand this. So we got through for the check variable. And we got the numpi array, which represent the image. This image is actually the first image that the video captures. This year, the bullion, we can use it for various operations such as checking whether the video is running or not. So you may have to check that while doing your programs. And the frame is the most important one because we will use the frame object, so we'll use this umpire array, which is a three dimensional array because it's a color image, so it has three bands. And you know this from the previous lectures where we did image processing. Okay. And we will loop through this frame and show it using the image show method. So I'm show image show method of CV two library. So we will recursively show each frame of video being captured. So I hope that makes sense. So before we do that recursively, I would like to show a window down here. So cv two, I show, and let's put a name for the window capturing and pass the frame object in there. And also, remember that when you pass an image show method, so when you're showing a window, you want to make sure that the window is closed. And you do that using the Cv weight key method, and you can pass zero to allow you to press any button and close that window. And what you want to do is cv two destroy all windows. So when this button is pressed, you destroy all windows. And actually, you want to put this up here, so the video is not released before you press this key. So what happens is that Python executes these lines, and then it waits for you to press the key, and then it releases the video, and then it destroys the actual window that you're seeing on the screen. Okay, let's see what will happen now. Surprise, I've got only two teeth. You didn't know that. Okay, I'm joking. I have more. But so what Python did here is that it triggered the camera. So it triggered the camera here, and then it read the first frame of the video. So the very first frame as soon as the camera triggers, it reads the first frame and then we printed out that frame and it's here somewhere in the command line, and then the script slept for 3 seconds, so it didn't do anything. It waited for 3 seconds, and then CV two with the AMShow method, it created a window where it showed the first frame of the video. So the picture that you just saw is the first frame of the video. And then the actual frame, the window is still open, so it's waiting for a key for us to press. So if I press a key now, these last two lines will be executed. So that means the video will be released and this window will destroy. So press key, and yeah, that happened. So Python is processing a video frame just as simple images. That means you can also apply methods such as cv two dot, CVT color And you can pass that frame in here and then save it to color BGR gray. Save it in a gray variable. So what I'm doing is that I'm converting the frame, so the color frame into a gray image. And actually, I have to do this up here. And then I can show the gray scale version of the image here. Okay, let me try it again. So that's a gray scale version that is showing using imshow method. So that's the idea. Now, how about showing an actual video, not a single image there? Well, the answer is that we need to use a wild loop here. The reason we need to do that is that a while loop, what it does is that it executes some statements infinitely until you break the loop at a certain point using statements such as break, for example. So the idea is that we need to put all the code up to here. So we need to put it in a while loop, and I'll do just that. So you can either use a shortcut from your keyboard depending on your keyboard or go to edit lines and then indent to indent these lines. So here is a shortcut. But anyway, then you want to write while true. And then everything goes inside the wild loop as easy as that. But we haven't finished yet. We have some more things to do here. But first of all, I'd like to actually make sure you understand the wil loop. So let me trigger Python console here quickly. So what Wil loop does is that, let's say while true, print. Let's say one. If you execute that now, one will be printed infinitely. So my console is getting very busy here, and I can interrupt this using a keyboard interruption operation, so Control C or control that if that doesn't work. So Wilby is saying while true, which will be always true, execute these lines. But if I try to run this now, what will happen is that Python will trigger the capture video capture, and it will show the window, but it's just one window only. So just an image is the first image of the video. Because what's happening is that the wire loop starts, but it goes. It creates a frame, the first frame of video. So the current frame, which is the very first frame where the video starts, then it converts the frame to a gray scale image. And then it slips for 3 seconds, okay? Then it shows the image. And then what the i loop does here, it waits for you to press a key. Then if you press a key, the process stops. So what you can do in this case is to enter another. Let me make some space there. So you need to alter this value here, so the arguments. When we enter zero, it means that any key that you press on the keyboard, it will close that window. But if you enter, let's say, 2000, that means the script will wait for 2000 milliseconds, which is 2 seconds. And let's see what will happen here. So it shows my face first, then it waits for 3 seconds here. Then it waits for another 2 seconds. Then it shows the other frame. So it's very slow, just like that. Okay. Now, if you press any key, nothing will happen because you remove the zero from here. So in that case, I'll forcly stop the script here, Control C. We don't need this time slip anymore, and we also need a conditional here. And before doing that, we'll store this action in a key variable. And then we say I key is equal to or the method, and then you pass a key from the keyboard. So if the equals Q, then break the while loop. And let's put it 1,000 this time. Okay. So now what this will do is that it will capture the video, I will start the video, and then it will iterate through all these lines. So it will create a frame, convert it to gray and show the frame here, and then it will wait for 1 second. And if you press key from keyboard, it will break the wire loop. And then if it breaks, and the video that release will be executed, so the video will stop and the window will be destroyed. But if you don't press any key, this will wait for 1 second, then it will show the next frame. And then after 1 second, it will show the next frame and so on. So, save the script, execute. So the video is improving. Yeah, looks good now. Okay, if you press Q, you'll stop it. Okay, let's improve it more. Why not one milliseconds? Hey, how are we doing? So, it's working good. And you can also see here that the check bullion, the numpireA is being printed at every iteration. And we can stop this now if we press Q, just like that. Now, if you want to know how many frames are being generated there, there is a nice trick we could do. We could create a variable, let's say, A equals to one outside the y loop. And then here, you say, A equals to A plus one. Then after the loop breaks here, you want to print A. So what this will do is, when you run the script, A gets a value of one and then when the wall loop starts running, so it will go through the first iteration, and it will increase A value by one. So A equals to one plus one. So it will be two. So A will be updated to two. Then it will go up to the end and then it will start up again. So this time will be A again, equals to two plus one. So A will be three at the second iteration, and so on, or you can put this to one actually. So if we have two iterations, that means A will be two, and if we have three, it will be three and so on. And then we print A here outside the loop, okay? And let's see what we have. I'll keep the video running for 3 seconds, and we will see how many iterations we'll have. So capture one, two, three, and stop. So the last value that was printed out here is a value. That means we had 51 iterations in about 3 seconds, which is, let's say, around 20 frames per second. So our camera, my camera is capturing 20 frames per second. Let me execute this one more time, the last time. So if I put my finger here in the camera, so I blacked out the image and you'll see that the numpy array is now zero, zero, zero. Because the frames of the image, all it has is zero values. So there's zero intensity in the image. Oh. Okay, that's what I wanted to show you in this lecture. So as I said, once you have these frames, you can apply operations to them, so you can draw rectangles there, detect images, and so on. We'll do that, so we'll build our real world application. By implementing some motion detection in our frames, and then we'll capture the times that an object enter our frame, or video, and we'll have a list of those times. So I hope you love this lecture, not hated it, and I'll see you in the next one. 121. App 3: Webcam Motion Detector App: Welcome to this new lecture of course, and this is quite special. I happen to be on camera because in this lecture, what you're going to build is a program that detects moving objects in front of a computer webcam. And then what it does, it records the time that the object entered the webcam. So the video frame and the time when the object exited the video frame. So now there is a moving object. In the frame and if I go away, you see that there's no green rectangle now in the video. And now I show up again, move out again, and so on. So we're going to build this application from scratch using Python. Yeah, we have a lot of things to learn, such as image processing and video processing as well, and so on. And lastly, what we do then if you press Q for quit, what you get is a graph. And as I said, the graph will show the times where the object entered the frame. So we're dealing with an interactive graph here. And yeah, these are the times when the object entered the webcam, like this one here, and here it lasts longer. And so, well, this can be a great application if you want to detect objects. You can throw you can put this application of this Python program in Raspberry server, for instance, which is a small server, and you can put it somewhere maybe you want to detect animals. You may want to know when this animal is entering the frame and when it is exiting or with people as well, if there is the case. So yeah, this is a program, and I hope you enjoy it. We have quite a lot of code to write, so let's get started, and I'll talk to you in the next lecture. 122. Detecting Moving Objects from the Webcamp with Python: Hey, here we are again. And in this lecture, we will continue building our real world motion detection program. Now, before I go and write the code, I'd first like to explain to you the architecture of the program that we will be building. So how this program is able to detect motion in the video. And I assume you already know how to build this script. So we built this in the previous lectures. And what this script does is that in case you've missed it, Hey. So what this does is it triggers the video, as you so. From the computer webcam. So we're processing frames here in this Wile loop, and so on. So you know this. I will not go through them right now. So what we need to do next is we need to process those frames that are being iterated in this Wile loop. And I've got some pictures here to illustrate my ideas, my concepts. Let me go to the directory where they are located. And so what this motion detection program will do is it will trigger the webcam just like our current script does. And one condition for the program to work well is that once you trigger the webcam, the first frame of the video should be the static background. So if you're planning to use this program, let's say you set up a webcam on a laptop or a raspberry pie server. Let's say you want to detect the movement of a certain animal in an area. So first, you want to trigger the camera while while the background is static, and then you want to use this background as a base image so that you can compare the other images. And then Python can detect if there is a change between the first frame and the next frames. So that's one thing you need to do. And so this is an example of background. And then something, the animal will appear on your camera. Then what you have to write in your script in the program is at first, we would want to gray out this image, so the background image and the current frame of the camera. You'll store the first frame of the video capture in a variable and then you'll convert that frame to a grayscale image. Then the iloop will go through the current frames and you'll do the same for the current frame, so you'll convert them to grayscale and then what you'll do to these two gray scale images of the current iteration of the loop, you'll apply the difference between them. This is the difference, an example of difference frame of Delta frame, if you can say it like that. In this particular image, you will notice that behind me, there is a lamp of the room. Normally, you don't be able to see the lamp, but Python is actually making the difference between the frame where I was appearing and the background frame where the lamp is visible. So it comes up with this gray image where each pixel has a certain value. So it has some intensity values. All right. So that means, for instance, the high intensity values like this one where I am means there is potential motion in this area here. While the black areas imply there is no motion. But you also see some light, black pixels here because when I appear on camera, there is shadow behind me and so on. But we will apply something else later on, which is called the threshold. So we'll basically say that if you see a difference in the Delta frame in the frame that I just showed you, if you see a difference of more than 100 intensity, convert those pixels to white pixels, okay? And for pixels that are below the threshold, convert them to black. Okay. So you come up with the outline of the object that is moving in the camera in the frame. So we're doing all these processes inside the wile loop. And then once we have calculated the threshold frame inside the loop, what we'll do to the current frame is we'll find the contours of the white objects in the frame. Okay. So for this particular image, we would have contours around this object here and the contours around this and around this as well. Then we will write a four loop that will iterate through all the contours of the current frame. It will go to this contour to this, this and to this one. And then inside that loop, what we'll do we'll check the area of the contours. So this, for example, has an area of, let's say, 500 pixels. So if the area of the contour is more than 500 pixels, for example, then consider this as a moving object. If the area is, let's say, less than 500, like this one here is probably 20 pixels, let's say, this will not be considered moving object. I hope that makes sense. Then what we'll do next is we'll draw a rectangle around the contours that were greater than the minimum area. That will show those rectangles in the original image. So in the color version of the current frame. That means we will see a rectangle in the video while the video is playing, we'll see rectangle around the object. Later on, we will detect the times that the object, the moving object entered the, the video frame at the time that the object exited the background. But for now, let's simply focus on detecting the object, the moving object in the video. Okay, and let's go back to the script. Close this and this and this. Okay. And let's remove some unnecessary lines here. So we had a variable here, which we created because we wanted to see how many frames we had in the video. So we don't need that anymore, and we don't need the script to stop for 3 seconds. So I remove the time that slip and this one I saw. Okay. And now here, the first part is the most trickiest one. We need to figure out a way to store the current frame of the video. So as soon as the video starts, we want to store that numpy array in a variable and have that variable static, so we don't want to change the value of that variable while while loop runs in the script. And the way to do that is we would first need to create a variable frame for the first frame. So we need to assign it a non value. So none is a special Python data type that allows you to create a variable and assign nothing to it, but you have the variable there. So if you call this variable later, Python will not say variable is not defined. Okay, if you don't understand it, please hold on and you get it in just a while. And what you need to do now is to write a conditional and apply a continuous statement in there. Let me write the conditional first and then I'll explain to you what this does. So we want to check if the first frame is non And if it is known, we will assign the first frame, the gray frame. So what this does is that the script will run, the video will be triggered. Then the wire loop will start to run, and it will get the first frame or video, and it will store it in this frame variable. This frame variable will be converted into a gray frame. And then we say, if the first frame is known, which is true in the first iteration of the loop, this is true. So the first frame is actually non because we assign none here. Assign the numPi to the first frame. So the first frame, you'll get the grayscale image, which represents the very first frame of the video. So this happens in the very first iteration of the loop, okay? But then what will happen is Python will execute these other lines of code, and then it will go to the second loop. And what Python will do is it will grab the second frame of video. Okay? Let's say the first frame was a background image, and then suddenly an object appears in the camera in front of the camera. So Python will grab an umpire array that contains that object. So the second frame and this frame will be converted to gray. Then here we say I first frame is none, the first frame variable, we'll get the first frame of the video. And once we have grabbed the first frame, we don't want these other lines of code to be executed. Because here, we'll apply the difference between frames and we will blurry the frames and so on. So we don't want these to be executed. Instead, we want Python to go to the beginning of the loop and continue with the second frame. To do that, we need to continue here. So this means continue to the beginning of the loop and don't go and run the rest of the code. Okay. So the first frame is none. The first frame gets the value of the first image of the video, then goes to the next iteration. Then the next iteration, what we'll do is we'll grab the second frame of the video and then it will calculate the gray version of that frame. And then it goes again to the conditional. And in this case, is the first frame none? No, it's not because the first frame got the value of the gray image in the first iteration of the while loop. So these lines here will not be executed at the second iteration of the loop, okay? Great. That means we can now apply Delta frame, so we can calculate the difference between the first frame and the current frame of the image. So the first frame is the first frame variable and the current frame is a gray variable. But before that, we'd like to do something to the current frame of the image. We want to apply a Gaussian blur to the image. And a dot here. So the reason we want to apply Gaussian blur is that we want to blur the image, so we want to make it blurry, so to smooth it because that removes noise and increase accuracy in the calculation of difference. So this gets as parameter, the image you want to blur. And then so we're passing the gray image here and we're storing the blurry version of the image in the gray image again. And then we have another parameter which comes as a tuple, and here we need to pass the width and the height of the gaussian kernel. So which is basically the parameters of the blurriness, but 21 would be accepted numbers. And you also need another lost parameter. So that would be the standard deviation and I'll pass zero. Zero here is also commonly used. If you want to learn about them, you can go through the documentation, but these values would be good. So we're making the gray image blurry here. Then down here now, we need to compare the first frame of the image, so the background with the current frame. Let's call this the frame, and that would be equal to cv dot apps difference. So absolute difference between the first frame and the current frame, which is gray. Note that the first frame will also be a gray version, a blurrid gray version, actually. So we are comparing here to blurrid gray scale images. Okay? And what this will give us is another image, okay? And actually, I'd like to show that image here on the screen. CB two image show. Delta frame. Let's see what we'll get out of this. And before running the script, I'll disappear from the view first and then we'll appear. Again, let's see. Okay, nothing happened because I forgot to enter the name of the window. Let's call this Delta. Frame. And let's say gray frame for this. Now let me run it again. And here I am. So this is a blurrid grayscale version that's on here, and we have the difference. Okay. So you can see the lamp behind me in the Delta frame. Great. Press the Qiki and quit the video. Now, if I want to print, just to check the delta frame, This will allow us to see the difference between intensities of the corresponding pixels. So let me see. And if I quit this now. Here we go. So what we have here five means there is no difference. So in this area, there's no motion, probably, but then you have 174, which is quite white. So that means Python will classify this as motion. Okay, that was just to show you the values of the data frame. What we need now is to classify these values. So let's say we want to assign a threshold. So let's say if we have values that are more than 30, so if the difference between the first frame and the current frame is more than 30, we will classify that as white. So we'll say there's probably motion in those pixels. So there's an object in those pixels. And if the difference is less than 30, we'll assign it black pixel. Okay? So we can do that. So we are here. We can do that using the threshold method of the CV two library. Let's say fresh Delta equals to cv two, the threshold. And what this expects is the image. That you want to threshold, and then you want to specify a threshold limit. So 30 we at 30. And what color do you want to assign to the values that are more than 30? Well, you want to assign a white color which corresponds to the 255 value. Okay. And you also need one more argument here, which is the threshold method. There are quite a few methods out there, but we are using this method here. So threshold binary. You can experiment with others if you like. Great. And now let's see how this Fresh Delta frame will look like. CV two show thresh frame, okay. Fresh Delta. Great. Let's see. Apparently, I wrote this wrong Delta frame, not frame Delta. And one more typo in line 19, which is here CV two. Okay, let's hope this time will work. And yet another error. This time I've missed something here. Okay. This method here, so the threshold method actually returns a tuple with two values. And the first value is needed when you use other threshold methods. So the first item of the topple basically suggests a value for the threshold if you're using other methods. But for threshold binary, you only need to access the second item of the tuple, which is the actual frame that is returned. From the threshold method. So you want to access the second item of the tuple. Okay, I promise this is a loss error. Great. Finally, and this is the threshold frame. See you can see my outline there, but you also see some white areas here because of the shadows. So I am being detected as an object, but my shadows as well as are being detected as objects too. Okay? So you get the idea. Now, we can go right away and use this thresh Delta frame, which I called it thresh Delta. I should call it the thresh frame, you know, just for name consistency. So we can go ahead now and create contours of the white objects in the thresh frame. But before that, I'd like to do something else. I'd like to delay those areas. So I want to remove the black holes from those big white areas in the image. So basically, I want to smooth my threshold frame. And to do that, you need to use the delayed method of CV two library. So let's say we want to change the threshold frame, CV two, DLD, Again, you want to pass a threshold frame there. Now, if you have a kernel array and you want this process to be very sophisticated, you'd pass that array in here. We don't have any and we don't need one, so you need to pass none for this parameter. And there's yet another parameter here, iterations. Let's say two. So this defines how many times do you want to go through the image to remove the soles. So the bigger this number is, the smoother the image will be. Okay. Let me check it quickly. Oh, yeah, I changed the name earlier, but I didn't change it here in the I'm Shaw method. Fresh frame. Okay. So you can probably notice that the areas, the white areas are smoother now. So if I go away, you'll only notice a few areas that are there because of my shadow. So, it seems to be working so far. Let's create it now. Great. So we've got these three frames. What's next? Well, next is we need to find the contours or this dilated threshold frame. Regarding contour detection with OpenCV, you have two methods. So you have a find contours and a draw contours method. And with the find contours method, what you do is you find the contours in your image and you store them in a tuple. On the other hand, the draw contours method draws contours in an image. So in this case, what we want to do is we want to find the contours, and then we want to check the area of the contours. So let's say you have a contour like a circle, and so you want to find the area that this contour defines. So you want to store those contors in a tuple. So you want to write CNTs C and another underscore. Okay. That would be equal to. CV two, find contours. And then you want to pass the frame that you want to find the contours for. And it's good to actually use a copy of the frame, so you don't want to modify the threshold frame. So use copy here. Though so this is the first parameter, the frame you want to find the contours from and then you have the method retrieve. External. So you want to draw the external contras or the objects that you'll be finding in the image. And you've got yet another argument chain, prox symbol. So this is approximation method that OpenCV will apply for retrieving the contros. Great. So what we have is we are iterating through the current frame. So we are blurring it and converting it to gray scale and find the delta frame and apply the threshold. So the black and white image. Then we find all the contours of the objects of the distinct objects in this image. So if you've got two white continuous areas in your image, but they are distinct, you'll get two contours. So one contour for each of the areas. These contours will be stored in this CNTs variable. So we're talking about the current x what we want to do is we want to filter out these condors. So we want to check that we want to keep only the condors that are, let's say that have an area that is bigger than 1,000 pixels. For that, you need to iterate, let's say, for contour in CNTs. And if cv contour area of contour. So the contour that we are iterating through, if this is less than 1,000 continue to the beginning of the four loop again. So what this means is, let's say Python found three condors and it will go through the first one and it will say the area of this conor. So we use the conor area of the CB two library. If the area has less than 1,000 pixels, go to the next conter. So go to the second conor and check again and again and again. Otherwise, if the area is bigger than or equal to 1,000, the next lines here after the four loop will be executed. So what do you want to do if a contour is greater than 1,000 pixels? Well, we want to draw the rectangle surrounding that contour to the current frame. So make sure you are inside the four loop. So we are still iterating and So these are the parameters that define the rectangle, that would be equal to CV two dot bond rectangle or the current contour. So if the contour is equal or greater than 1,000 pixels, so if it has an area of equal or greater than 1,000 pixels, this will be executed. So we are creating a rectangle, and then we want to draw that rectangle to our frame to our current frame. So CV two rectangle. So we already consume this method in our phase detection lectures. And here we would want to pass the color frame. Okay. So that is the frame, and you want to specify X and Y. So these are the coordinates of the upper left corner of the rectangle, X Y, and you want to specify the coordinates of the right lower corner of the rectangle as well. So X W just like that. And also the color of your rectangle, let's see. Green and width. Let's say three. So what we did in these two lines is that we created this tuple with these four coordinates. And these values, this will be assigned automatically. So X and Y will get the value from the rectangle bonding this current control of the four loop. And then these values will be used to draw rectangle in the frame in the current frame. And then we want to show that current frame. So let me add it here. Image show. Let's call this call the frame and frame. Actually, this method here is bonding, correct. Alright, let me try the script now. A CV two has no attribute find contours. So here I've got a U there that shouldn't be there. Let's try it again. Yeah, that's funny. I tend to mistype this word contour area. Line 24, remove the U. And should be contour here as well. Okay. Contour is not defined again. I've got another one here. So bear with me. Try again. Uh, yeah, this time seems to be working. So no objects. Objects. No objects. Objects. Great. Great. So that's what I wanted to teach you in this lecture, and we'll continue with the next lectures because what we've done so far is that we can detect that object and we can draw a rectangle around that object. But this is not very practical. I mean, in real world, it's not enough to just draw a rectangle around your object, and then that's it. So what we'll be doing in the next lecture is we'll be storing the times that the object enters the frame when the object exits the frame. So we've got some more lines to add to this code. And I know this code here was quite a lot to consume, but I hope these are clear now. If you have any questions, please feel free to ask them, and I'll see you in the next lecture. 123. Storing Object Detection Timestamps in a CSV File ++: Alright, so I've got my motion detection program rounding here. And as you see, this is capturing me moving at the moment. If I move away, you can only see some shadows there. And so, well, this is great, but as I said, you may want to store the times where an object enters the frame so that you end up with something like this. So this is the first entrance. As the start time, here is where the object exited the frame and then the second entrance of the object and so on. So in this lecture, I'll show you how to build that table using this script. So we will add some more code here. And the way to start doing this is to first figure out the point, the line in the script where the status is changing from, let's say, motion to non motion. So we have non motion in here. So as soon as webcam triggers, let's say, the status is zero. So just a symbol that I'm choosing to denote that there's no motion in the current frame. So then you get that first frame, which has a status of zero, and then you grade out, and then you check if the first frame is none, and then you continue the loop again, and then you grab the second frame. So the status is still zero, then you apply the difference, the threshold, dilate. And then erate through contours. So if you find an area that is less than I changed this earlier, I put it 10,000. So I wanted to detect bigger objects because I was closer to the camera, so I wanted to adjust it. So depending on what objects you want to capture, you want to adjust these pixels here. So 10,000 is something like 100 by 100 pixels window. So we're checking if you don't find a window that is bigger than 10,000, then you continue through the beginning of the loop until you find a control with this size bigger than this. When Python finds that contro with that size, we want to change the status to one. Okay. And let's now print out that status variable. So what you want to do is print it at the end of your loop so status. And let me delete this numpy arrays, which are being printed. We don't need those and make some room here. So this is inside the loop, and I now expect to see the status of one or zero printed out depending on whether there is an object in the frame or not. So if this is working, that means we now have the actual status of the frame, and we can use that 10 for other things. So let's see. Okay, there's nothing at the moment. Let me minimize this so we can see the console, this as well. Great. So zero is being printed out, and if something shows up, now you see one. Again, one, zero, one, one, zero. Great. We can now simply apply a date time method, you know, such as date time does now. And that would record the time of each frame. So we don't want that exactly. We want to use daytime do now method, but not like that because that would record times for every frame. So what we want instead is want to know when the status changes 0-1, which indicates that there is an object entering the frame. So we want to record that time. And we also want to record the other time when the status changes 1-0, so the object exits the frame. Let's say status list, that would be equal to empty brackets, an empty list. And then I want to append the status of the object to that list. So after this loop finishes, which is here, so I want to be here at the same level with the loop, so I want to apply something outside the loop. So status list, I want to append the current status of the list here in this status list. Great. And to illustrate, to show you what this status list is about, I'd like to print that out, actually. And I would want to print out a list outside the wire loop, so I don't want to print out every time the loop iterates. So movement here. And quit. So these are the statuses for each of the frames. So zero, zero, zero, non movement, and then something entered the frame. And that something entered, like, let's say, 30 frames, and then the object exits the frame. And that's it. So what we want to do now is we want to capture what's next. So the next thing is we want to capture the time that we switch 0-1 and also 1-0. So basically what we're interested about is to capture the last two items of the status list. So let's say we have status zero. So we start with empty list, and the first item that will be appended to the status list is zero. And then the second item, let's say will be zero or let's say it will be one. And so we want to apply conditional to check whether the last two items of the list are changing. So I know this may be confusing, but once I write these four lines of code here, you'll understand it, and it will make a lot of sense. So we want to check if status list. So the last item of the status list, which has an index of minus one, remember, list indexing, if that is equal to one, and status list with index of minus two. So the item that was added first, the item that was added second is equal to zero. We want to record the daytime of this event in a list. So let's create a list here, say times equals empty. And then we go here, here, and we say times append, daytime, dot now, you know about this function already. So we want to append the current timestamp when this change occurred. So that means we need to import or from date, time, import date time. So daytime class from the datetime library. So we're basically recording the time when the status changed to one. And we also want to record the time when the status changes 1-0. So we would have a similar conditional, but this would be zero, and this would be one. Okay. So what's happening here is, let's go back to the start of the loop. So Python captured the first frame, and he converts it to gray and blurs it and applies a gaussian blur there to the first frame. And then we store the first frame in the first frame variable, and then we go ahead and calculate the difference between the first frame and the current frame, find contours, and then if this low finds contours greater than 10,000, the status variable changes from zero, so it started at zero, so it changes at one here. And that means this empty status list will get another value. But the first value is always zero, so the list will start with zero. You know, like here. So the very first value is zero. And so let's say for the next ten frames, it will be zero, zero, zero, zero, and so on. And then if an object enters the frame, and then the status changes to one. So we'll have zero, zero, zero, zero, and then one. And then what we're doing here is we're comparing the last two items of the list. Okay. And here, I'd like to print out the times list so that you see what's going on. And I expect to get an error at the first execution here because we have something more to do, but let's see. So, yeah, it says list index is out of range. So that means Python is having trouble accessing the second item of the list because the list has no items here, so it has no items. And then we add an item, so we add status. And then Python tries to find the second item, but there is no second item. So we need to do a trick here. We need to add two items. Okay. Let's say none and none. Now, let's execute the script again. So there's no object there at the moment. Now an object appears, it goes out again two times and one more time. So three entrances. And I quit it. So let me go through this list now. This is our times list. And so this is the time. So here, the month, the day, and how minutes and seconds, and then microseconds in here. So this is the start time when an object entered the frame for the first time. And then this is a time when the object exits the frame. So I stayed there for 2 seconds, so 51 up to 53. The next object enter the frame. So from this second to this, so for two other seconds, and then another third time 0-1 for 1 second. So we've got three entrances in the frame. So I hope that makes sense. This is good, but sometimes it can happen that when you're running the script, so you have background, then the object shows, and the object disappears, shows again. And then if you quit the program at this point, so let me quit it. You'll see that you have a start time here for the first entrance, then the end time, and then you have another start time here for the second entrance. But then you don't have the exit time. So you may want to add the end time of the exit of your last object, which happens to be when the window was quit. So you want to go here at the end, and the script is waiting for a key. So if you press quit here, the while loop will break. But before that, you may want to check the status. So if status is one, and in that case, you'd end up with this scenario here. So if status is one, when you press the key from the keyboard, you want to add another item to your times list. So times appended daytime that's now, great. So that should work differently now. So let's execute the script. No object. Object. No object, object in the frame, quit. And now we should have four day times here. Four times times, one, two, three, and four. So this here was recorded in this expression here. Great. And the next thing we want to do now is to throw this list into a pandas data frame and then into a CSV fol. So we'll have a start and an end column. And in the start column, we would have, for instance, this value, and in the end column, we would have the other values. So this one here and the last one. Okay. So first of all, we need an empty data frame, pandas data frame. So we'll be using pandas to create data frames, of course. So let me import pandas here. And let's say data frame DF equals to pandas DataFrame with columns start and end as easy as that. So that will create a data frame structure for us, which has no values, but it has two columns. And then the next thing you want to do is outside the loop. So once you have created once you have generated your times list, you want to iterate through that list and then append those values into the pandas data frame. So you need a loop, let's say, for I in range. And so here you'd have to iterate with a step of two. And you'd want to iterate as many times as there are values in the list. So you start from zero and then you'd end up at how many values you have in the list? Well, you can find that using the length method, so length times with a step of two. Great. So that will be for each iteration, DF solid data frame will be equal to itself. Dot append. So you are updating the data frame, and here you need to pass a dictionary. So for the start column, you'd want to enter times I and for the end column. So the keys of the dictionary here are start and end, and you'd want to append times I plus one. And you want to ignore index. So equal to t. Great. So what this is doing is, let's say, for I in range, this would be, let's say we have a list with six items. So we have three star times and three times. So that would mean range zero to six with a step of two. So for zero, we would do this. So we'll start from zero in the loop, and we would access the item with a zero index in times, which happens to be this item, for instance. So the first item. And then we append that item to the first row of the start column. And then we access the item zero plus one, which happens to be item with Index one, which should be this item, so the second item. And we append that item to the end column for the same row. So that's it. Then we go to the next item. So this time, we would start with index three, and so three here, add it to the start column and then four add it to the start column to the end column, sorry and so on. And lastly, we would have a data frame. And what you might want to do then is DF two CSV. Let's say times CSV. So we are exporting the data frame to a CSV file. Great. So let's see how this will go. It's getting quite dark here. Okay. And one more time. Frame, quit. And as you see, times the CSV was created in my file system. And so these are the times. I can also open it using Excel. So these are the start and end times. If you want, you can format them format cells here, and you can see the dates now. Great. Great. So that ends this lecture, and I hope you enjoyed it. We have quite a good script now, and to make it more beautiful, we would want to display these times in a graph. So that's how you turn your data into real information. And we'll do that through the next lectures. But before I'd like to introduce you to the Bouquet library, which is a library for interactive visualizations in the browser. So please follow the lectures in the correct order, and I'm sure you will learn a lot. Talk to you later. 124. Introduction to the Bokeh Library +: Hi, and welcome to this new and very exciting section of course. And in this section, so throughout the lectures of this section, you will be learning how to generate visualizations on the browser with Python. So we're talking about interactive visualizations, and we'll be using the Bouquet Python library to do that. So Boke is a Python library, and it's quite new. And with Bouque you can grab data from various data sources, data file formats such as CSV, Python list, JSON files, and so on. And you can create beautiful visualizations on the browser. I used to be a user of Math Plus Lib and Seaborn. So two other Python libraries that are used to perform visualizations with Python. But I would say, Boke is more modern. And once I introduce it to you, I'm sure you'll be using it for your data visualization projects. So in this section, I'll be showing you how to create line graphs and scatter plots and also how to combine various plots into one chart and time series graphs as well. And we'll be writing the code in the Jupiter notebook, formerly known as the iPython notebook. And the Jupiter notebook is like a combination of Python console, so you write interactive code, but you can also save the script that you write. The Jupiter notebook looks something like this. Okay. And I'll show you how to install the Jupiter notebook in the next lecture. And so Jupiter is great for doing data analysis and visualizations and web scrapping and other exploratory analysis. So I'm sure you'll love it. And here, let's move on to the next lecture. 125. Creating Your First Bokeh Plot: Great. Now you know what boke is because I explained that in the previous lecture. In this lecture, I'll show you how to build a very basic book graph. Yeah, so we'll start from scratch and step by step, we will improve that graph. Yeah, let's say this is your first book graph or maybe you have built book graphs before. So before taking this course, you know, a few things already. Still, I would suggest you start from here because I'll show you the correct logic towards building graphs step by step. Ah, let's go ahead and do this. Mm. I'll be using sometimes I'll be using Jupiter notebook to write Python code, and in other times, I'll be using the Atom editor. So the Jupiter notebook is a good place to start, actually, because it will allow us to write some interactive code. We can just write a single lines of code and see what it does. So that's great for starting off with a library so you can explore the library by tasting small pieces of code. And with shift and right click on Windows over folder, you can go over here and open command window here, and this will open a command prompt in the current folder. So on a Macro Linux, you can maybe do something like open terminal here or you can open a terminal normally, and then you can CD to the path to your working path. So I'll be writing the code in this directory. And to install Jupiter, you'd say PIP install Jupiter Notebook. And this is a requirement already satisfied because I've already installed Jupiter Notebook. If you haven't, you can just go ahead and do this, and, you know, it will be installed for you. And to start Jupiter Notebook, you'd say Jupiter Notebook, just like that. And that will open a Jupiter Notebook on Local host. So it's like a service based notebook. And yeah, if you create now, you create a Python free notebook. And name it. Basic graph just like that. And in the demo folder you'll have this basic graph dot IPYNB, which stands for IPython notebook, but now IPython notebook is renamed to Jupiter Notebook. But the extension still stays the same. And you also have these checkpoints, which are files automatically reduced when Jupiter saves your sessions. Now you should keep your command front open, and then this is where you write the code. You know, if you don't prefer to use Jupiter books, you can use your favorite editor. So that would be Atom or Vim or the default Python IDE, and so on. It doesn't matter much. And I'll be using comments to comment my code, and that will help you read and understand my code easier because, you know, I'll be writing some code here and some code and later on like that. And I'll be explaining the code as I type it in. But sometimes you forget what I typed here and you're struggling to understand it, but if I have some commands here, let's say, plotting the X and Y values. And if I write this comment here, Python will not read it as code, so it will ignore it, but you can read it and you will assume that I'm writing this comment for the next block. So I write the command, I leave no space and I type the code there. And then I leave a space there and I type some other code there. So it's another block that doesn't have to do with this command. So this comment will be about this block of code there. Sometimes I may want to apply specific comments about specific lines. For example, this one here. In that case, I'll write the command just there. So let's say for the X values here or something like that. Great. And the first comment will usually be about the script. So what we'll be doing is making a basic boe graph. This will be a line graph. Great. And I'll leave a space there, and here I start the code. So first of all, I'll be importing Boke I'll be explaining this later, but bouquet has a few interfaces. And the first interface is bouquet plotting. So it's called the Bouquet plotting interface. And I'll be going through the interfaces later. So for now, let's focus on how a graph looks like and how the code looks like to build a booger graph. So from Bouquet plotting import you import the figure object, which is the most important object in Bouquet because this will contain like a container where you add points, you add lines, and you had labels for the points, and you had grades for the plot, legends and everything. So you'll add everything into this figure object. That's it. And then you need to have some helpful tools from Bokeh that comes from booke dot IO interface. So from that, you want to import output file and show. Yeah, that's basically what we need. You'll see what all these are in just a bit, and then we need to create some data. So let's create some fake data there. Prepare some data. I'll be using lists. Let's say, one, two, three, four and five. So that's for the X axis. So in the plot, these values will be mapped along the X axis. And then we have the Y axis there. Let's say, six, seven, eight, nine, ten. Note that these lists have to have the same length, in order to plot them in Bukit. Otherwise, Bouquet will throw an error. I will say that you know, Bouquet will start to take pairs of this list. So it will take one and six, and it will map these along the X and the Y axis. So it will create a point with coordinates one and six, and then two and seven, and so on. I go through five and ten. Then if you add a line number here, say, seven or whatever, Python will say, Oh, I didn't find a pair for seven in the Y axis. So you get an error. Great. So we have the data. Prepare the output file. So here is where you use the output file function. And there you pass the name of the HML file that will be created. So you can choose every name you want. And then the next thing to do is you want to create a figure object instance. You have the figure class there. You have inputed it and you can use it now, just like that. I'm storing that in the F variable. Let me comment this. Create figure object. And then finally, create line plot. And the way to create the line plot is by referring to the figure object that you created, and then you apply the line method if you want to create a line. And the line expects from you to pass the X array with data and the Y array as well. So I know that everything I'm passing here are the minimum requirements to build a plot. But there's a lot of features that you'll be adding later here in the code so that we enrich our plots with features such as legends and labels and colors and transparency, et cetera. But this is the backbone, so to say. And once you have created a line, all you have left to do is use the show method to show your figure object. And to execute that in Jupiter, you can just press Control and Enter. Wait a second. And I got an error there. Oh, put it should be output file. Sorry. Execute again, and here is the line graph. Anyhow, if you look at this, you see that the first point of the line is at coordinates one. So this is the X axis, one for the X six for the Y. If you look here's one and six, and then you have two and seven and so one up to the last point, which is five to ten. Five and ten. Yeah. So that's a graph. And this is not an image graph. As you can see, I can move this around and you also have a couple of tools here. So these are called tools. And what you can do with this is, let's say, this is a pen, and you see this vertical blue line here, that means that the Pen tool is already activated. And if I move my cursor like that, I'll pen around the graph. If you click, let's say, the Wheel Zoom, you'll see that both Pan and the wheel Zoom are activated now, and I can use the wheel of my mouse to zoom in and out. Now remember that I told you, bouquet produces interactive graphs. So here it is. However, this is just a basic functionality of interactivity because later, as I told you earlier, I will be adding widgets here that interacts very powerfully with a graph. Anyway, basically, you also have this box Zoom that you can zoom in a certain area of your graph. You also have this reset to there, which actually resets the graph to its default view. And what's left, we have this help button, which brings you to the Bouquet documentation, and I'll go through the Bouquet documentation later, which is very helpful for you to get help from. And it's also a safe button in here which you can use to save your plots in PNG graphs, images. So if you ever want to convert your graph to images, you can use that button. And a, that's about building a basic graph, and I'd like to give you some practice activity, you know. You know, here I used a line graph, but you can use other types of glyphs. This is how these geometries are called in Boha and you can get an idea of what glyphs you can use, you can apply to your figure by doing D and F, which is the object instance of your figure object. You will see here, let's find line. Here is line. So that's the one you used. But I'd like to ask you to make your own graphs using triangle first Alana circle. So, that would be very easy. Instead of line, just pass these things here and see what you get. But try to make the graph from scratch instead of copying mine. And let me comment this. I forgot to comment. You can also play around with some other data to see how that goes. And yeah, that will make sure that you understand how to create a very basic bouquet plot. And in the next lecture, I'll show you how to use some more real data. So we use is here, but in the next lecture, we will use CSV files. So plotting from a CSV file, we'll be creating the same graph. See you there. 126. Using Bokeh with Pandas +: Good. We were able to create a line graph using this code, and I hope you played around with this code a little bit and got familiar with it. Now, you see here that we got two lists as output. In this lecture, I'll teach you how to use CSV files to feed your boket graphs. And I'll use this code as a reference. So I'm just going to, you know, you need to press Escape. When you press Escape, you can apply shortcuts keyboard shortcuts to your cells. And you can see a list of shortcuts in here keyboard shortcuts. And for instance, what I want to do now is I want to copy a cell with C, and then I want to paste I want to paste that cell below with V. But first of all, you need to be in command mode. So to go into command mode, you need to press Escape, as the help script says. And yeah, make sure escape and then C and then, and you get another cell in here. Also, I'd like to actually remove this header here and go to view, Togle header and then TogleTolbr as well. So I have more space for you here. So this is the code I'll be working with. Enter, and yeah, I'll be working in this code for now. And let me go here. This is working directory. I'll just go ahead and create a CSV file. Let's say dot dot CSV. Yes, and I'm just going to edit it with Nopats. You can use Excel if you like. So I'll just have two columns here. That is the header, and then one for X, six, for Y, two and seven and three and eight, and four and nine, and one more, ten. Save that. Close it. So note that data dot CSV is in the same directory with basic graph dot IPYNB and go to your script. Now, we are importing Boca here, but I'll be importing panels as well. So let's mention this here and pandas. Let me use lowercase B and import pandas. Yeah, prepare some data. Hmm. So, I assume you know pandas. So basically, the data frame is the main object, and you want to create a dataframe from CSV fall which is data dot CSV, just like that. And then, let's create two variables here. So the X variable will be equal to DF. Square brackets, the X column. So don't confuse the X column with the X variable. They just happen to have the same name. Okay. And also the Y array, the F. Y? Okay. Yeah. That should do it. Let me rename this. From CSV. Execute. And you get exactly the same line as we did earlier with the plain list in here. And, ah, that's basically how you feed your bookie plots with Panda's DataFrame arrays. So again, um, just for the sake of clarifying things, this is the data frame. It has two columns, and you have the X column then. So that was stored. Actually, this is the index column, this one here. This is the actual data of that column. And you also have the Y column there. So, that's it. As you see, Bouquet is able to read playlists, so Pythleis as this one here, and actual and also data frame or a series. So this is called a serious. You can check that. Yeah, a serious. And, yeah, that's it. DD to delete a cell. And yeah, we'll move on with some more lectures there, see you. 127. Creating a Time-Series Plot +: All right. In this lecture, you learn how to make time series graphs. We're talking about data where one of the axes. Normally the X axis consist of dates or times. Let's say we have temperature observations for several dates, and we're going to have to plot these values along the X and Y axis. I've got some nice data here that We're going to take from this link. So it's a CSE file. You don't have to download the CSV file actually, because we will passing it as a link directly to the CSV method. So what we've got here is a date column and some other attributes. So you may want to plot the data along the X axis. And then in the Y axis, you want to show one of these features. Let's say this attribute, close. So I'm going to close this. I don't need this file because I'll use a direct link and let me create a new cell. So I'll be using, again, the bouquet that plotting interface here. And also import pandas. The key here is that we will be using a pandas data frame, and then we will parse this data time column as dates so that Python reads them as dates and actually is able to plot them in the X axis. And then we'll be using a line glyph to plot this data. So a line glyph would be, you know, you can use circles, triangles, et cetera, but you can also use lines. So you'd pass line here, but then the size doesn't make sense because you may want to pass line with for the line. So not size, but line with. And, you know, if you execute this you don't see circles anymore, so it's not a scatter plot now, but it's a line chart. So we'll use the same concept for building this day time graph, time series graph. So first thing you want to do is load the CSV data inside Python. So panel read CSV, and you can pass actually the link this link directly to the CSV method. So how convenient is that? And then you want to pass the parse dates parameter year, and you want to specify the name of the column where these dates are. And the name of that column was date. So if you remember from the CSV file that I opened earlier, that was date. And so once you load the data frame object, you want to create a figure object. Let's say width equals to 500 and fight. Let's say 500 for now, then we check how it goes, and we can change it later. So we have the X axis type parameter here. So what this should do is you want to make your axis, your X axis spatial so that it can read date time data types. And so to declare that you have daytis, you need to pass a daytime argument as a string there. So that's it. And then what you want to do is apply the line object in there. So similar to this now, you need to pass the X axis and the Y axis. So the X axis here should be DF date. And the other axis is, let's say close, so the closed column. And let's make the line orange. And what else? Maybe a transparency of 0.5. And specify where you want to save this. So under what name HTML Time series dot HTML. And lastly, show the plot. And let's see. And something is not working, so Python is not being able to pull off the data there. Oh, I need to pass the data here as a list actually. So Yeah, it looks better, but it also looks a bit squeezed. So what you can do here is you can change this to, let's say, 250 and you'll get a better graph there. Now, if you want to extend it to the entire page, there's something you can do there. You can actually pass the responsive and set it true. Well, let's see. So you get a bigger graph there. And of course, you can zoom in to see some details there. So for May 8, you have a value of one indity. You get the idea. So that concludes this lecture, and I'll see you in the next one. 128. More Visualisation Examples with Bokeh: All right let's sum it up now. So we were able to generate graphs, and you saw that until law we generated single graphs. So for instance, here, you'll see a line graph. Now, if you want to combine multiple glyphs in one plot, that would be very simple. So let's say you've got two plots. You will add a scatter plot there. So you'll need to add a circle glyph. So just below this line glyph or above that doesn't matter. So circles with these coordinates or we can change them. So let's let's double the X axis. Eight times two for I in this list, which closes here. And then this should be the size, let's say eight and olive. So this is how you get multiple glyphs in one plot. That was very easy. And so I believe I give you a good introduction to the Bouquet library. And I believe you see its potential, so it's great to actually use Bouquet for generating visualizations. Now, if you want to go deeper into bouquet, so you may want to have to plot different types of graphs, out point you first to this resource. So this is documentation, the bouquet documentation. And this is about plotting with glyphs. So what you have here is various examples. We use this one actually and other ones as well, lines. And you can also plot patches. So basically, you pass the coordinates of each of the points of the polygon here and bouquet will draw the polygon there. So these are the basic things. And here I'd like to stop a little bit. So this is called a quadrat plot, actually, this one here. So instead of passing a circle of line, you'll pass a quad. And what this consists of is the top. So the upper border of your quadrant. So for instance, the first quadront here has a top border of two and a bottom of one. So it's border with one and two. And then a left would be one and right, 1.2, so one left and 1.2 right. And then you have the next quadrant, which is this one here with its coordinates as well, and so here's the colors so you can use CSS color codes if you want, besides using color strings like red and orange and yellow, and so on. So the reason I stopped this plot is that we'll be using this plot to actually visualize the times for our video program. So the times when an object enters the video frame and when the object exits the video frame. It would be great if you start thinking about this now how you're going to make use of the CS file that we generated in the video program earlier and plot that file in a similar graph like this one. There are some tricks there, and I don't expect you to fully solve this, but it's good to think about that. You also have this gallery here, the Bouquet gallery. Here we have some beautiful plots. You've got the histogram. If you click one of these, so, for instance, I'll to make this map. So you can simply copy this code and paste it in your script and run it, and you'll get the same map. That's what I wanted to teach you about Bouquet, and we'll be using it later, as I said, for visualizing these times when an object is moving in our video frame in front of our webcam. So I'll talk to you later. 129. Plotting Time Intervals from the Data Generated by Webcam App: Hi, and welcome to this new lecture. So what I'll do here is I'll give the final touch to our motion detection program. And specifically, I'll build a plot using the Bouquet library where I will visualize the times that the object enters and exits the frame, the video frame. And the final output will look something like this. So what we've got here is a plot with an X axis. Which is plotting the daytime, while the Y axis doesn't have any sense, actually. So just a vertical extension of the bars which is here. And so what we've got here is, let's say, I started the camera this date so 17th of March. And so this first capture here is, you can see it started at this date and it ended after 4 seconds. So this object entered the frame in the start date and stayed for 4 seconds there and then exited the video frame. So, similarly, we have this other object. So still on 17th of March. And then we've got this other here. And then here starts the other day. So 18th of March, and these are the hours between these days. So 4:00 eight, 12, 16 and tent. And you can also see that I have added hover capabilities here so that when I hover the mouse over these bars, I get this information. And you can also zoom in here. So if you want more information about this, you can see the information clearly here. So that's the product. Now, what the script is doing at the moment is it is producing the start time and the end time of the object entering the frame in a CSV file. So specifically, the program is triggering the video from the webcam. And then you got some objects in there. Press cue for quitting. And so what you get is the times the CSV. Where each row represents the start time and then time. Okay, you know this already. And so at the moment, what we've got here is also a list with the status of the current frame. So this has, let's say, 100 items, that means we had 100 frames in this seven second video. Now, the first thing you may want to do is a small improvement here very quickly. This list, if you're having a webcam capture a long video. So if you're running it for many hours, this list may get too big, so to avoid memory problems, you may want to go here. So here you're checking the last item of the list and the item before the last item. So the last two items, that means we don't need these other items. So we only need to keep two lost items only. That means just after we append the new status here, so we say status list equals to status list, but with only the last two items. So if I execute this now, what I'll get is only the last two statuses of the video frame printed out as a list. So the list is printing here. So that's an improvement for the sake of memory. Now, how do we get around building a plot with bouquet? So first, we have to think about the structure of our scripts. So this plotting object that we'll be creating using a quadrant, so this will expect a data frame to be sent as an input. So we actually have a data frame here. And we are sending the data frame to the times the CSV file. What I'll do here is I create another file, Python script, say plotting dot pi. And here is where I'll write the script, the code for plotting the data. In that case, that means we need to fetch the data frame of this motion detector program to this script. So what you can do is you want to say from motion, detector, import DF. So that will make available the DF data frame that is being generated in this motion detector program, which means that when you want to run the program later, you'll be running the plotting dot pi with Python. And so when you execute Plotin dot pi, plotting dot pi will call for execution this motion detector dot py script. So the video from a webcam will start and then when these loops ends, this data frame will be generated. That means after that, the script, the code of the plotting dot pi will be executed. So here you'll be getting the data frame and plotting it and so on. I hope that is clear. So let's go ahead now and import the plotting interface of Boke. So from BokePloting actually will not be importing the entire plotting interface. We only need figure show and output file. Let's keep it tight there. And then let's go ahead and create the figure object. And X is type will be of type date time. Let's set a height of 100 and a width of 500. And let's make it responsive. Title of the graph motion graph. Okay. So once we have a figure there, we want to plot a glyph in that figure. That glyph, in this case, would be a quadrant, so quad. So a quadrant would be more appropriate to plot these time intervals there. And so the trick to have this quad glyph to visualize your date and your times along these X axis is to pass left to right, bottom and top parameters. So for left, you'd want to pass the start time, so left of the box of boxes that you see here. So the left border would be the start time while the right border. So DF would be the end time. So here is our CSV, which is not what we're using, but this is a structure of the data. So start time on the left, and then end time bordering the right of the rectangle of the quadrant. And then here is a trick we can do for bottom. We'd want to keep a fixed value. So zero for every quadrant, and then one for every quadrant as well. That's it. Color is not a problem. Let's say green. And I'd like to try this for now. So I'll put file. That would be graph dot HTML. Show the Pi figure. And let's see what is going to happen this far. So Python, we don't want to execute motion detector now, but we want to execute plotting that Pi. So that's our main script where we get started. And I've got a stupid syntax error here from Book a plotting figure, I bet you knew it that I missed the import keyword here. So from BokePloting import figure show file, save and try again. And here's the webca Object. Object again. Another time. Quit. And let's see what's gonna happen now. And yet another error, responsive. Good. Sorry about that. Try again. First object, and second object there, and one more? Quit. And we should see the graph. Yeah. Yeah, it's looking good. So I can see here and you can also notice that we've got quite an unnecessary granularity here. So we don't need all the stickers here. And also, you can see here that this is 19 seconds, which means that it's 19 seconds past the last minute. So if it was, let's say, 15 minutes and 19 seconds. So 20 seconds of the 15 minute and so on. So you don't really see the big picture in just 10 seconds of video, but also to make it more informative, I'd add a hover tool to this bar so that when I hover the mouse here, as you know, you should see the start and end time so that you can see the complete time there if the labels here are not enough. But first, let's remove the stickers here. So we go back to the script and let me put this down. The way to do that would be we need to modify the figure object, so the P variable. And so we're working on the Y axis, so Yaxs. So we access the Y axis object of the figure object, then minor tick color, and we want to set it to none. So this ticks here. Also, you can see that we also have a grid. So we don't want these intermediate lines here, and we can do that by accessing the grid object, which is list, so you need to access the first item of the list. So there's quite a trick there, but you have to make peace with that. So ticker say desired. Number of ticks. So that's the method and set it to one. So let's see how the graph will change this time. And it's a good idea to put the graph another name so that we compare the two graphs. So graph one for this. And let's see. Here. And quit. And I've got an attribute minor tick color. I tend to put this wrongly. The good thing is Bouquet has quite a good error handling, so it's a similar attributes or minor tick line color. So it's actually able to read what you input there and it suggests you what to input so minor ti line color. So we've got a line here. So try again. Let's see this time, what we'll get. So now it looks cleaner, as you can see. Here is our previous graph. This is the new one, so we don't have the horizontal grid lines and the ticks in here. And I thought of stopping this lecture at this point. And the other lecture, I'll show you how to add these hover capabilities to your graph. So I'll talk to you in the next lecture. 130. Implementing a Hover Feature: Great. We have a graph visualizing the time intervals when the object entered the video frame. Now, let's go ahead and modify our code so that we add a window, a window will pop up here when the user hovers the mouse over these quadrants. Let's do that. And the Boke tool to implement the Hover functionality is called the Hover tool. And that is accessed from the lower level interface called models, so boket dot models. So you want to import the Hover tool. Let's now see how we're going to use this inside our script. And basically, this is a method that expects from you some arrays with data so that the Hover tool method will display them when the user hovers the mouse on these quadrant. So if the cursor is on this particular quadrant, let's say, the data for that quadrant will be displayed on the pop up window. So what you want to do is once you have created your figure, you want to create a hover object, which will be equal to the Hover tool. Which has a two tips parameter there, and this will get as argument list of tuples, and in every tuple, you want to specify the lines of the pop up window. So let's say in the first line of your pop up window, you'd want to have a start string, and beside that, start string, you want to have the array with your data. This has this spatial decorator here. So in our case, that would be the start column from the data frame. So we want the start time, and then time as well. So for the string and and for the name of a column. So that should do it almost. But we need to add this tool using the at tools method. So the hover object, we need to add it to the tool menus. So this should be a dot. And that's it. And we're going to have to add more here, but let's see what we get this far. So Python plotting dot py. Here's an object, another one, and a third one and quit. So yeah, here is a graph, and we're almost there, but not yet. So as you see, for some reason, Python is having trouble fetching the values of the start and the end column. And you also notice that we have two columns for each of these rows here. So the first thing you want to do is remove this column. You don't need this because Bouquet is adding it by default. So that's it. And now to solve the other problem, the main problem of question marks is by adding the column data source method. Which comes from the booked models low level interface. So column data source is a standardized way to provide data to a book plot. So if you've got data frames, lists or other objects, for some functions in book you need to convert them to a column data source object. Which actually is very easy. And let me do it here. So we grab the data frame here, and then let's say column data source, CDS, that would be equal to column data source. So the methods and the data you want to pass to it. So we have a data frame in this case. And then once you do that, you need to adjust here, not the figure object because we're not passing any data here. We're just constructing the environment for the plot, but you need to modify the quad. Method. So specifically, you want to pass source parameter here, which should be equal to the column data source object. So CDS in our case, this one here. So you're telling Bocket use this data, and then you don't need to point to the data frame. So you just enter the names of your columns there. So let's see what we have this time. Object, another one quit. Here's a graph. And yeah, almost there. But the problem is this time we're not getting the days in the correct format. The reason for that is that the Hotol method. So here, we're here. The Hovertol method is not being able to fetch day times data types. But that's nothing to worry about because what we can do is we can convert the data times to strings in the data frame. So before before we pass the data frame to the column data source object method, we convert the start and the end columns to string datatypes. So you already know how to work with daytis. So in this case, we'll do some daytime formatting. So what we could do is create another so a new column, let's say, start string. So the string version of the start column, which should be equal to the existing start column. Dot DT, which enables you to do daytime formatting and STR f time. And here is now how you define your date to be displayed. So you'd want to display the year first, and then the month, a dash, and the day after that, and maybe a space there, an hour, minutes and seconds. And the same goes for the end column. So string, and here, and the same here. And as you can assume now, we need to reflect those changes in here. So this should be start string, and this should be the end string. So we are displaying these strings now to the pop up window. And let's see how this goes this time. First object passes there, second, and last and one more. Quit. And we have a problem here, I suppose. I didn't change the values in here. So I did completely the wrong thing. I shouldn't have changed the days in this quadrant object because this is datetimes because we have defined the axis daytime here. So this express daytis. So here should be start the original start column and here the end column. So by mistake, I put those values in there. So start string in here and string in here. So that should do it this time. Let's double check. Everything looks good. And let's see. Here go. Yeah, we were able to grab the data. Let's see. Yeah, this looks good. So now I believe this graph is quite readable, and I believe you're able to pull out some information out of this graph. So you can see how long an object stayed in the video frame and when you started and when it exited the frame. And I hope you'll find this useful sometimes. As I already said, you can use a raspberry pie server. So we just a small computer and host this application in that server. And of course, you can build and of course, you can mount a camera in that server and have it capture some video for your needs. Most importantly, I hope you learned from this practice activity, and I know that was quite a lot to consume. If you have any questions, though, I'd be happy to answer them. So please feel free to ask them in the discussion board. And I'll talk to you later on in the next lectures. See you. 131. App 4 Part 1 - Data Analysis and Visualizations with Pandas and Matplotlib +++: Hi and welcome to one of the most important projects of the course, the data analysis and visualization project. As you may know, Python is undoubtedly the best programming language for data analysis and visualization. Python was able to overtake languages which are used in data analysis such as R, and the secret of Python is a vast variety of libraries which you can use with Python. And that means you can combine your data analysis reports and plots that you create with Python with other Python libraries make complete applications such as web apps or even desktop apps, automate things, et cetera. So Python is definitely the right tool to use with data analysis. It's very powerful. Now, in this section, I'll not simply show you the code that does this operation and that operation, but I will also show you the logic behind data analysis, what you should do when you have a data analysis project. Since I have a degree in geospacial data analysis, so I'll show you some of my expertise in the field. I'll give you a dataset of 45,000 records, and we are going to turn these data into information. That is what data analysis and visualization is about turning data into information. For example, we are going to answer questions such as, what is the day of the week when people are the happiest? And we're going to use our data for that. The data are simply data, but knowing the happiest day of the week, that is information. Now, one important part of this section is the data visualization part. So let me show you some of the plots we are going to create in this series of videos just to give you an incentive, a motivation for you to actually watch this series of videos. All these graphs are interactive. So just to give you an idea how these graphs will look like, here are some plots that we will create. This particular one shows the average rating every day, so the date is along the X axis, and the average rating is along the y axis. Then we're going to make pie charts such as this one. And also other interesting types of charts. In fact, I'm going to show you the way how you can make any type of chart that suits your data, your needs. And that is going to be quite easy, actually, because I'm going to tell you the trick, the logic behind that. And the good news with these graphs is that you don't have to do a lot of configuration because these are beautiful out of the box, and that is made possible by the library that we're going to use. So get ready for this, and I'll talk to you in the next video. 132. Exploring the Dataset with Python and Pandas +: Welcome back. When you're doing data analysis, the first thing you want to do is you want to familiarize yourself with your data using the tool, the data analysis tool that you have chosen to use for your particular project. In this case, the tool is Python. So what we're going to do in this video is we are going to load the data into Python using a Jupiter notebook. Then look at those data and extract some very basic information about the data, such as looking at what column names we have, how many rows we have, and other simple attributes of our data. Let's do that. I'd like to let you know that I created an empty folder named review. Underscore Analysis and I put the reviews that CSV file in that folder. You can find these reviews that CSV file attached to this lecture, so as a lecture resource. So please download that and place it in a folder just like I did. And then you should be able to locate that folder from the Jupiter homepage, which is localized 8888 slash three. So I created that folder directly in my user's folder, so this is the folder. I can click that and here is the reviews that CSV file. In your case, you can create it wherever you want and then locate it using this directory tree here. While I am in this folder from Jupiter, I can go to the new drop down list and go to Python three to create a new Jupiter notebook. So the Jupiter notebook has been created. I can rename this to something else, the name of the Jupiter notebook. Let's keep it simple and say reviews. Rename and that will get at IPYNB extension. Let me make some more room here so that you see more code. I'm going to toggle the header off. And now let's start coding. The very first thing we want to do, of course, is import Pandas, the library that is used to perform data analysis with Python. And then we want to create a variable which is going to hold the data that is equal to Pandas read. Since we are working with a CSV file, the method we want to use out of the Pandas library is Read CSV. In parenthesis, we want to pass in single quotes or double quotes, wherever you like. The path to the CSV file. Now, if you don't type in the name correctly, you're going to get an error. So let me try to execute this cell using Control Enter if you are on Windows or Command Enter if you are on Mac. As I warned you, I got an error. It says no such file or directory because I mistyped the file. So reviews. This time, if I execute, I don't get an error, that means data was loaded successfully, and I can press Escape, B, Enter, and call the data variable and Control Enter again to see the data frame. So we can see that we have one, two, three, four columns. And we also have this index column here added by Pandas automatically. Basically is a range of numbers starting from zero. So that is the first row of our data, this one in here. That has this index of zero. And it ends at the last row. You can see that this is the first row, second, third, fourth, five row, and then Jupiter is not displaying the row after row five because there are a lot of rows, and it would be impractical to see them here. However, you get to see the last five rows of the data frame. And that gives you an overview of the data frame. However, what I like to do instead is just print out the head of the data frame, which is the first Rows only. So the first five rows, that gives you a more compact view. It gives you an idea what columns you have and what kind of rows you have also. So it's good to have the head of the data frame displayed in here. Then we can press Escape. B and create a new cell here. Enter to write some other code. You can get the shape of the data frame by accessing the shape property. So that is a method with parenthesis. That is a property. It doesn't need parenthesis. And then you get to the shape of the data frame, which is basically the number of rows and the number of columns. You see one, two, three, four columns. You might also want to be enter, display the columns that your data frame has. Even though we have them there, this is yet another way to see the names of the columns by accessing the columns property. Next, usually when you are working with data, you have some specific columns that you are interested about, which could be one column or more. In this case, we might be interested to see an overview of the column to see what the minimum rating is and what the maximum rating is and the distribution of those ratings and have them as a graph here displayed here so that we can have a better understanding of our data. So I'm going to do escape, B, enter and data dot Hit. So this will be a histogram. With parenthesis, we are interested to see the distribution of the ratings. Therefore, I enter the rating column here, I say string, execute, and we get this graph. Let me explain you what that graph means. What this means is that, for example, let's start from the right. This bar here, this first bar means that we have around 24,005 star reviews, ratings. You see, for example, we have this is a 5.0 star rating. So we have around 24,005 star ratings in the whole data frame. And in total, we have 45,000 rows in total. Then the next this bar here, these are 4.5 star ratings, like that one in there. And we have around, let's say, 7,000 of those. Then we have four star ratings, around 9,000, perhaps, 3.5 star ratings in here. This is three star ratings. It's about 2000. Then we have 2.5 star ratings. This one in here, two star ratings. 1.5 star ratings. That's the lowest number among all the ratings. So people don't leave a lot of 1.5 star ratings. And we also have this one star ratings in here. It's not the bass graph. I don't like it personally, but it's a quick way so that you know how your data are distributed. You know that, okay, we have data 1-5 and five is the most occurring value in your data. And that's about this lecture. This so you can get an overview of your data frame. In the next lecture, we are going to zoom in into our data frame to actually be able to select particular rows or particular slices of our data frame to see individual values. So, in other words, we are going to use Python to navigate through our data and select particular sections of the data and display them. So I'll see you in the next video. 133. Selecting Data with Python: Hi, welcome back. In this video, we are going to zoom in data into our data frame by selecting particular columns of the data frame, particular rows, multiple columns, multiple rows, specific shelves in the data frame, we are going to learn how to apply conditions so that you can extract data based on different filterings and so on. So let's start. I'm going to open Jupiter. And I'm going to go to the review analysis. Folder and click on the Jupiter Notebook file. Now, something you should know is that if I at a new cell here and I try to access the data variable, we are going to get this name error. Data is not defined because when you just open a Jupiter notebook, the cells are not automatically executed. So this is not a variable yet in the name space of this interactive Python session. Therefore, you should execute the cells either by going to the first cell and press Shift Enter, then Shift Enter to execute the other cell Shift Enter, Shift Enter, or you can go to this button. To run all the cells. So press that, restart and run all cells. And then you are going to get access to the Delta variable like that. Right, so I just wanted to make sure you know you are aware of that specific behavior of Jupiter. Now, I want to put some headings here, some text. For example, I want to put the title of this first section that we did in the previous video. I want to name that something. So I want to add a cell above this cell. Therefore, what I do is, first, I make sure that I'm not in certain mode, so I press escape for that. Then I press A on the keyboard, and the new cell is going to be added. Then I press without entering the cell. So without entering, make sure you press escape. Without entering the cell, we press M, and that will convert the cell into a markdown cell, which means the cell now does not expect Python code. It expects Markdown text, which is basically some sort of language. For example, if we write two of these hash symbols, and we're right over view of the data frame. And then we press Command Enter, that is going to be converted into a title, into a heading. Basically H to heading. If you add one more, you're going to get smaller fonts and so on. So two is fine. And then I'm going to add here, so convert this into markdown with escape, and then right here, selecting data from the data frame. And then B to enter the new code cell, so that is a code cell that is a markdown cell. So let me show you how you can select a column of the data frame. Escape. Select a column. Control Enter. B, Enter to select a column, you can use that syntax and then execute. And this is a column. Now, you could ask, why do we need to select a column? What's the interest behind that? Well, the answer is that this is the first step of doing further analysis. For example, if you want to extract the mean, the average of the rating column, then we first would need to extrat the column and then apply that mean. The method mean executes, and that will give you the average rating of all the courses for the entire data frame. So the rating of all the 45,000 rows. So that is one example why we would need to select a column. But let me delete the mean now. So that is how to select a column. Now, escape B, Enter. Select multiple columns. Execute, B, Enter. To select multiple columns, you'd use more or less the same syntax. But instead of inserting one single column here as we did string rating, in this case, we would insert a list of multiple columns. Let's say we want course name. So one string, a comma off the string, another string, rating, and then execute. And that will give you basically a data frame containing only those two columns. Now, there's a fundamental difference between this output and that. You can also see that this is formatted differently with lines, so it looks like a table because this is actually a data frame. So if you apply type, of that expression. So that is expression. We used. If you execute that, you'll see that this is a data frame data frame. But if we see the type of that other expression, you're going to see that this is a series. So a series is another data type of pandas just like we have. Data frame we have series, and series are used to represent single columns like this one here. So the rating column only. But when we have more than one column, Pandas uses a data frame like this. So that was just an information to keep in mind. It doesn't change much in how you do the statistics later, but it's just good to know how Pandas works. Let's see how to select ARO. With rows, it's a bit different. Of course, you first need to refer to the data variable and then to I lock. And then you need square brackets. Inside those square brackets, you should put the index of the row you want to access. For example, let's say we want this row here or let's refer to this better. So the Python mega Curse with a rating of five, which has an index of three. Let's see if we are going to get that row. Executes. So yeah, it seems that is the Python mega course and it had a rating of five. The timestamps this on here, so 333. Let's see the entire data frame. So 333, that one in here. That row is that. The type of this object is a series again. So Pandas uses series also for rows, for single rows. Let me delete that type, execute again. This is the output. Next. Selecting multiple Rose. B Enter data. Again, iloc is what we use. And this time, since we are working with multiple rows, we want to input a slice. Let's say we want from Index one to index three, those rows, and we get this data frame this time, not as serious. So we got the row with Index one and the row with Index two because the upper index is not included in the slice as it almost always happens with Python. So times 512, timestamp, 511. 512, five, 11. Index one, index two. Yeah. So that is how you get multiple rows. Next. Selecting a section. What I mean by that is basically a cross section. So particular columns and particular rows will give us basically a slice of the data frame. For example, we want to select particular columns. Again, we use the same syntax as we did previously. So you see up here when we selected multiple columns, so course name rating inside a list. Course ename Rating. So this will give us basically that. And then out of that data frame, what we do is we apply Alok because this is a data frame object, right? That was also a data frame object. And since we could apply Alok to that data frame, we can also apply Ioc to that data frame. It's the same object type. So out of that we get, for example, from row with index one up to row with index three, without three, and we get this section of the data frame, which is, again, a data frame, object type. So only course name and rating columns and only those two rows. And lastly, selecting a cell. We follow the same syntax, the same logic. So let's say we want to select this cell here. So the cell that is the cross section of row with Index two and the timestamp column, that one in there, timestamp, Index two, right. What we do is first, we extract the column using the same syntax that we used to select a column, which is this one in here, Delta. Rating data timestamp this time. So basically, that gives us a column, but out of that, we can apply lock for a series, too. So this is a series, not a data frame, but series also could use this log property and then get the index two out of that, and that gives us the value, which is a type string. So if you wanted rating instead, you'd get a float because ratings are float, 4.0, that one in there. And that is how you get a cell. Now, this method is very consistent because it uses the same syntax as the other methods. So it's consistent with the other methods of selecting data, but there is a faster way to do the same thing using data, the at property. And first you pass the index of the row and then just the name of the column, rating, for example. And that should give you the same value. So it is recommended to use that when you are selecting a cell. So that's about this lecture. In the next lecture, we are going to go further into selecting data, but using conditions. For example, give me all the ratings that are greater than four. So filtering based on conditions in the next video. See. 134. Filtering the Dataset: Hi, welcome back. In this video, you are going to learn how to filter data from your data frame. By that, I mean extracting particular groups of data based on different types of conditions. For example, let's say, in our data frame, we have different courses, even though here you only see the Python megacurs because we are only seeing the first five rows. We have other courses with ratings. So if you wanted, for example, to know the average rating for a particular course only, then you'd have to filter the data by applying some conditions. So filtering allows you to do analysis on a particular group of your data. Let's do that. First, I'm going to assign a number to each of the main headings. So that was an overview. The second lecture was selecting, so that's number two. This time we'll at number three, filtering data based on conditions. Right. Let's apply one condition first. So I'm going to create a markdown cell and say one condition. Let's apply a condition which would give us the data frame where the ratings are greater than four. To do that, you'd have to follow this syntax. Now, first, make sure that you have your data variable in the name space by executing this first cell. Control Enter to execute that cell. Now we are sure that data is in the name space. This is the syntax data square brackets and inside here goes the condition so we said that we want the data frame where the rating is greater than four. Therefore, we say column rating is greater. Let's leave some space, greater than four. If we execute that we get a data frame and all these rows have a rating of 4.5 or more, not four because it's greater, it's not greater or equal. If it was greater or equal, we'll also get the four ratings, 4.0. But this is not the case here, so this is what we get. You see, for example, that rows with Index 012 were not included in the data frame in the output data frame, and you can see the length of this using a function Python length function. We get 29,758 rows that have a rating of greater than four. Another way, if you don't want to use native Python function, another way is to use count. So that is the data frame object, and the data frame objects have a count method. And you get this output, which basically says that we have this amount of values in course name, this amount of values in timestamp, this amount in rating and comments. Because commments have these non values that is basically a non existing value, it doesn't exist. Therefore, we have 4,927 ratings with comments where people actually wrote something. So the rest, this minus that gives us a number of non value comments. Of course, you can apply different types of statistics to this now. For example, this is a data frame right. How do we extract only the column? How do we select only the column rating? Well, you could take a look at here, selecting a column. So this is how you select a column data rating. Now, this is the data frame. Therefore, you apply rating, and you get the ratings with a value of 4.5 or more. So to understand this, what we do is, let's say D two is the data frame that we get based on that condition. So it's a data frame. That data frame has a rating column. So that's what we get. That's the same thing that we did in here, data rating, D to rating. I hope that's clear. That also allows you to apply functions such as mean. You get the mean of the ratings greater than four. I'm going to leave it as it was then next is multiple conditions. Let's say we want to filter the data frame where the rating is greater than four and the course name is equal to the complete Python course built ten professional OP apps. Right. So this course here. Let me copy the string so I don't make any typos. This is how you do that filtering, double filtering. You start with that. And then instead of putting one condition as we did in here, we would put two conditions which would be separated inside parenthesis. So the first condition there and the second condition in there. So as a first condition, we'd put the same thing. So that delta rating is greater than four. So you see the condition is inside the parenthesis. That's the first condition. The second condition is where Delta, we said course name is equal two, the string, the complete Python course, column built ten professional OP apps, right, execute, and we get the data frame based on that filtering. So since this is a data frame, that data frame, we can extract rating out of that and then get the mean of the rating column, and that will give us this number. So the average rating of the ratings above four for that course. And this is the filter data frame again. And that is about this lecture. In the next lecture, we are going to look at filtering data based on times. So how you can extract portions of your data frame for a particular period. So you see we have this timestamp column here, and that ranges 2018-2021. Let's see how you do that in the next video. 135. Time-Based Filtering: Hi, welcome back. In the previous video, we did some filtering based on conditions. So we applied one condition here and multiple conditions here, two, to be exact. But we can apply more than two using the same syntax. All right, so here we applied the condition by comparing numbers. So we worked with number types, rating the rating column had number data types and the course name column where we said that we want only the records where the course name is equal to that string. So these name column, he string data types. So string data types, number data types. But how do we compare? How do we filter data based on data times? It is not as straightforward, but it's not hard either. So let's do that. Let's add a new main section. So let's say this time time based filtering. Right. So let's extract the reviews that were left during the second half of 2020. Let's try to apply the same syntax as there. So we start with the data frame and square brackets. Now, this time we need two conditions. Why? Well, Because in the first condition, we would say Delta. Time stamp is greater than first of July 2020, and the other is Delta time stamp. Is less than 31st of December. So greater than first of July means second of July, third of July, fourth of July, and so on. So we want those data for that period. But we also want the other condition that the data shouldn't be greater than 31st of December. That's why we use that lesser than 31st of December, which would be 30th of December, 29th of December, and so on. But how do we write 1 July here? Well, for that, we need a datetime object. We cannot just write a string, write like first seven, 20, 20 Python is not that smart. It's a programming language. Well, it is possible that the Python developers could write something to read that kind of string, but it would be prone to errors. You know, someone writes it differently, someone writes it like that. And so on, you want to be explicit to be able to avoid unwanted errors. And by explicit means we need to use a proper datetime object type. So I'm going to import from daytime, import datetime. So we import that daytime object out of the daytime library. Don't forget to execute that cell and go down here and use that datetime object that we just imported from the daytime library, which would be 2027 means July and first of July. So that would give us 1 July in the proper data type. We can do the same for this date time, 2020, that would be 12 for December, 31st of December. Right. Now, I think it's more meaningful to say greater or equal than that first of July and also less or equal. So you get the idea to include those dates as well in the period. Now let's execute this. And we get an error. Let's go down here to read it. It's a type error, which means that the wrong type was used somehow. But let's read more to understand what it is. So this operation, this comparison operator is not supported between instances of string and datet that date time. So it seems like that operator was applied between a string and a daytime that daytime. Right? So which one is the string here? The first one. So data timestamp is a column containing strings. So timestamp contains strings. These are all strings. Even though they look like date, they are not dates. So the idea here is that Python cannot compare date times, so that date time with those strings. Therefore, we need to instruct Python to treat those as date times as daytime objects so that then Python is able to compare two daytime objects, which is more meaningful than comparing a string in the daytime. To make Python, read these as day times, we need to go to the top of our script. And when we read the data frame using the CSV method, we need to add another argument, which is parse date. Through that argument, we tell Python through the square brackets which columns should be treated as date times. So timestamp, parse dates equal to square bracket timestamp. Don't forget to execute that cell and then go down here, execute that again, the cell. We get another error this time, again, a type error. It says invalid comparison between that and that. So this time, you see that this is for that. So this is a datetime UTC. And that daytime is that one. So Python is trying to compare those two, which even though they are daytime objects, both are daytime objects, Python is still not able to compare them because one of them, which is this one here, is a naive daytime object, which means that daytime object doesn't know about its time system. Therefore, Python to be on the safe side, it tells you that, Okay, I don't know what to do with these two day times because I cannot compare them since I don't know what time system they are. So even though they might look like this is smaller than that, this could be actually greater than the other one because this could be another time system, we should make that greater. To understand the importance of explicitness in programming, imagine an air traffic control tower. They have this application that receives signals from two airplanes coming at the same time passing by this tower. One plane is coming from USA, one plane is coming from Indonesia. The application needs to process the time sent by these two planes. And in that signal, besides the time, the application also has to know the time system of each of these two date times. Otherwise, if those two valleys would just say 6:00 A.M. America and 7:00 A.M. Indonesia, the program would think there's 1 hour difference. Then it could mess up a chain of other processes, and that could be dangerous. So explicit is better. So in short, to be explicit, we need to declare a time system for this date time, just like this one has a time system, and you can see that. Let's add another cell here, and you say data, time, stamp, execute, you get the series. But also down here, you see date time 64, it is UTC, UTC. So let's declare datetime also as UTC. Do that using TZ info, this argument, which gets a value an object type, a UTC object type, which needs to be imported. It's a specific time system object. So go to the imports and say from PY TZ Import, UTC, don't forget to execute that cell, go down here and do the same for the other data time. So another argument Ts that info equal to UTC, execute. And this time, finally, we got the filtered data frame. You see the dates in here. 20 2012, 30th of December. And also down here we see 1 July. With quite a low rating, sadly. Anyway, that's how you can filter data based on timestamps. Thanks for following. I'll talk to you later. 136. Turning Data Into Information: Hello, and welcome to this new video, which is going to be a bit different from the other ones. In the previous videos, I showed you some techniques to filter out data from a data frame. And that was basically accessing columns and rows and cells and also applying conditions when accessing these columns or rows or cells of a data frame. However, what we have done so far is just extracting data out of data. This is still not data analysis because the goal of data analysis is to turn data into information. That is what data analysis is about, but this is still not information. For example, let's say we want the ratings above four, and we got this data frame, but it's still a data frame. It's not human friendly. It's not information. Information would be if we instead got the average of the ratings above four. So we would end up with one single number. That is information because it's human readable. It tells us something, or maybe we could create a plot, a graph where we could see the ratings over time. We see the graph, and we can see a trend and we can learn some information from that graph. Turning data into information is what we're going to do next, and for this particular video, we are going to answer a series of questions. In other words, we are going to extract some information, such as we're going to get the average rating, the average rating for a particular course, and so one. Now, you should be able to actually write the code before me because you already know, for example, how to extract the rating column. And I also gave you some clues that you could use a mean method to get the average rating of that column. So let's start with the first information. The average rating for all the courses for all the times. That would be Data rating mean. And that is the average rating. So just like we had here in selecting a column, Delta rating. That's what we do here as well. So that gives us a column, and that gives us rating. Right, next, average rating for a particular course. This time we have to apply a condition which is delta course name is equal. So double assignment operator is equal to one of the courses. Let's say the Python mega course built ten real world applications. Now, if you miss a single letter in the string, you're not going to get the expected result. Let's say you wrote small A instead of uppercase A, and you get an empty data frame. If I change the lowercase A to uppercase, then we get the filtered data frame, and out of that, we want the rating column. So those are the ratings for the Python mega Cs, and mean is the average of the Python megacurs the average rating, which is a bit higher than the average rating of all the courses. Right, average rating for a particular period. Data, I'm just going to copy this and pass here. So we have this first condition, that second condition. So we're talking about this period. You can change that for another period, let's say, the entire 2020 from first of January to 31st of December. Now you can split this expression and still get the same output entering by pressing Enter after the t operator. And you still get the filter data frame out of that we get to ratings and out of that, we get the mean. That is the mean for 2020. Next, average rating for a particular period for a particular course. I'm going to copy this by pressing CC and click here and press V. And then after this condition, so one parenthesis, two parenthesis here I'm going to add the end operator. And press Enter, press Enter again. And here I'm going to add the other condition, which is this one in here. The course is equal to that particular string, the Python mega Core. Execute. We do have a mismatch of parenthesis. You see that this square bracket is highlighted in red. That means we should remove it. Execute again, and this is rating. For the Python mega course for 2020. This is how you get information out of your data. Let's carry on with average of uncommented ratings. So uncommented ratings. You know that let me put the head of the data frame here just for convenience. So you know that we have a comment column here, which could be an NaN, which means note a number, so it's a null value or it could be a string, something that a student wrote as a review for a particular course. We want to get the average of the ratings that have no commands. So to do that, you say data, the condition, data comment, is null. This is a method actually, and it gives us a filtered data frame with only the rows that have the comment value as NaN. The opposite of that is not null. Then you get the rows with comment. What we want is null this time and out of that, we want the rating column and the mean. That is the mean. The opposite of that would be, of course, not null. And we see that the average rating for ratings with comments is higher than the average of ratings without a comment, which I think is normal. People who like the course maybe tend to also write something to express their gratitude or I don't know, but this is telling us something. Right, number of uncommented ratings. Well, it's easy just copy that, paste a tear and instead of mean, you say count. And this is the count. The opposite of that would be not null. So ratings with comment count. And that plus that, I'm sure, gives 45,000, which is a total number of rows of ratings. So ratings with no comment ratings with comment. Next, number of comments containing a certain words. In the data frame in the comment, let's say, some students talk about the accent of the instructor. What's the average of those ratings that contain accent? Are people complaining about the accent and how many people are complaining about the accent of the instructor? Let's get that information. Again, the condition is that Delta comment, the string of that comment contains the word accent. What do we get is an error. The problem is that Python cannot mask with non boolean array containing null values. So Python cannot search in those null values in comment, cannot search for a string in these types of data. So we want to tell Python through the NA argument set to fold. In that case, Python will ignore those new values and it will only search for accent in the comments with a string with a value. And this is a filtered data frame. So all these comments are actually mentioning the word accent. How many of them? Those are the ratings only. The count of the ratings is 77. So 77 out of 45,000 total of course, the average would be simply that, but changing that count to mean. And it's a low rating as I was expecting. So because the courses are taken from students from different countries, some of them may find the accent of the instructor unpleasant. So maybe they are leaving a negative comment and a negative rating along the comment. And that concludes our lecture here. Thanks for following. In the next videos, we are going to do some plotting, which is a lot of fun, in my opinion, and it's a beautiful way to represent information to the public to the user. Thanks, and I'll talk to you later. 137. Aggregating and Plotting Average Ratings by Day: Hi. In this video, I'm going to show you how to create a plot of daily average ratings. So our graph will show the average rating for each day. To do that, I am not going to work on the previous Jupiter file because I like to keep things separate. So for the visualization part, I'm going to create a new notebook. I'd suggest you do the same. So first of all, we need to load the data frame. So I'm just going to copy that cell from the previous notebook and copy it there and just print quickly the head of the data just to double check everything is right. Yes, so these are the Delta, the raw Delta. Then press Escape and press B on your keyboard to create a new cell. Press Enter to enter the new cell, and let's create that graph. But before we create the graph, we need to do some sort of data aggregation. Right we are turning data into information, but our data are quite raw. You see that for one day, we have multiple ratings left by different students. For example, on the second of a prill second of a prill we have this rating, we have that and that, and that, and so on. We want to aggregate those numbers into one average rating. How do we do that? We do that. We can do that by using the Pandas group B method, which produces a new data frame. So it's going to be a new data frame, but with aggregated data. So some new data which are averages of the raw data frame. Let me show you how group B works. So I said that group B produces a new data frame. Therefore, I'm going to create a new variable where the new data frame is going to be stored. So day average is my new variable, and that would be equal to data. So that data frame group B. I really like this method. It's very intuitive. So you are grouping these data. By. What do we want to group by? Well, by timestamp. Let's see what that gives us. So I'm going to print out the average in here, the head of the average execute and let's see what we got. We got basically the same data frame. That is because group was not able to group the data by timestamp, because the way group works is that group B tries to find identical values in that given column. In this case, timestamp doesn't have any identical values because each value is unique, you can see, it's the same day, but this review was left at this time. The other review was left at this time and so on. So each value is different. Therefore, before we apply group B, we need to do some processing here. We need to add a new column in the data data frame. I'm going to name this column D with capital D. I'm just trying to be consistent with the names of columns. Since these are with capital letters, they start with a capital later. I'm going to create this new column with a capital later. So data day equal to data timestamp. That DT DT is a property which gives us access to a number of data time attributes such as date, sorry, date, you can do month. And so on. For now, we need the date. Let me comment this out, so I'm going to select them and press Control slash or command slash to comment them out. And I'm going to show you the new data frame. So that is the data frame. So what I just did is that I extracted from this timestamp, I extracted the date only. Therefore, what I got is that for each timestamp, I got the date. So for this timestamp, it's second off April, second of April, and so on. So this way, we got some identical data. You know, if you want it month, you'd get the number of the month. So four, four, four, and so one. But we need date, so I'm going to keep date there. Now we can uncommon this and let's delete data dot heat because we don't need it anymore. And now we can try this group by method again, but be careful. This time we need day here. As we said, we want to group by day. Let's execute and see what we get. Maybe it's not the result we were waiting for. So you see that day is not yet aggregated because we need to give another command here. We need to tell Pandas the method of aggregation. So do you want to aggregate based on the mean or the count? In this case, it is the mean. So we'd say dot mean, the method, execute, and this time, this is what we got. So that's just the head. But if you print out the entire data frame, you see that it goes like that up to this date. So for each row, we have one day, first of January, second of January, third of January, and so on. So that is the average rating of all the courses for that day. Now, you need to understand this product. This is, as I told you, it's a data frame type. So Panda's dataframe, but this has one column. So that is not a column. Day is not a column. Day is actually the index. You see that if you say day average that columns, rating is the only column. And if you want to access rating, you do like that. Rate, and you get this series. Now, what is this? This is the index. Therefore, if you want to access the day column, you don't do it like that because that is a syntax to access columns. When you want to access that special column, so that index column, you want to say dot index. And then we get this series which is type index. But you can easily convert it into a list. For example, if you like to plot them. So just like columns indexes, such as this one, are also list like types. So arrays of data. Let's now do the plotting. To do the plotting, we are going to need the MT plot leap library. So I'm going to input it in here. So import MT plot lib PyPlot. We need that module of the library, and a good practice is to use SPLT. So you'll see on the web that everyone uses PLT. So if you want to be consistent with other programmers, you want to import that a PLT. That also makes your job easier because you don't have to type that down, but you can just say PLT, as we will do here. So PLT dot plot is the method, and this method basically gets two arguments, the X and the Y. So we are building a graph with an X and a Y axis. Along the X axis, we are going to have the days. That means we want the average dot index. So that array there. And along Y, we want the average rating column. Execute. I got an error, PLT is not defined because I forgot to execute this cell so that the import is valid. Now I can execute this again, and this is a product. Along the Y axis, we have the dates, which I know they are a bit unvisible, but we are going to fix that. Along the Y axis, we have the ratings column. You see that it starts from 3.8 somewhere here up to five. Now, matplot leap picks that range automatically by looking at the data. Our rating column, if you take a look on it, you say the average rating. If you extract the max, the maximum value, you'll see that it is 5.0. And if you see the minimum, you see that it's around 3.8. One day, students left a 5.0 average rating, so all of them. Another day they left 3.8. So matplot lip is putting those two as the limits of the Y axis instead of starting the axis from zero up to five, and that would make the plot less readable. So that's a good thing of MT plot lip. The bad thing is, as you can see, this graph is not interactive, so it just an image file. You cannot have pop up capabilities so you could see some values if you over your mouse somewhere. So matplot lip cannot do that. However, we can improve this a little bit by declaring a figure object and give it a fixed size argument of let's say 253. That is the width, and that is the height of the plot. So now you can see that we have a longer X axis and a shorter Y axis. Now, if you don't agree with this graph, if you think that this is still not readable, it doesn't tell you much about the trend. So if the rating has been increasing with time or not, then what we could do is we could downsample the data. So instead of extracting daily averages, we could extract weekly averages, and therefore, we would have less points along the X axis and a smoother line. So in my opinion, these are too much data. It's unreadable, it's not useful. Let's downsample them with a better graph in the next video. So this is what you learned in this video. You learn how to group data and you learned how to plot them. Now, let me make a small revision of the group by method in case you are still confused. So let me remove that in another cell here and let me print out the head of the aggregated data frame. So you see we have rating and we have day index here. What happened with course name? With this column? What happened with the comments column? What happened with the timestamp column? Well, they disappeared because this mean method only works with columns that have number values such as rating. I cannot calculate an average on that column, comment or course name or timestamp. Therefore, columns such as common time samp and course names will be automatically dropped deleted by this method, and only those columns will be kept. Similarly, you could do a count instead of that. In that case, you'd get a different data frame. So you see that we have the count of course names, which means that 46 rows have been created for that date. In other words, 46 reviews. So we have 46 ratings, whatever you like to call it. We have seven here because what Pandas does is that it doesn't take into account non values such as this one and that one, and so on. Therefore, we could have this count plot. So we show how many ratings we had each day. And that is what I wanted to teach you in this video. Thanks a lot. I'll talk to you later. 138. Downsampling and Plotting Average Ratings by Week: I'll come back. In the previous video, we developed a plot showing daily averages of ratings, but also the daily number of ratings. In this video, we want to rebuild this graph but on a weekly basis. Let's do that. So let's organize this data frame a bit. I'm going to click here, press A, Enter, press M, Enter, and give this section a title rating average by day count since we did both averages and counts. Execute that cell. Now we need a new cell here, B rating average by week. Again, make sure you have access to the data variable. So this is my data data frame. Otherwise, you have to run this cell first and then perform the next operations. So the first thing we want to do is we want to I'm going to copy that line. And what we want to change from this is first, we need to give to create a new column in the data data frame. So let's name it weak. And we extract from timestamp do the T dot. Should it be weak? Let's try that out. Or just print out the entire dataframe. All right. We get a warning. Let's ignore that for a while. And we get the week column. So we see this is the 13th week. That's the first week. Let's see. Actually, what is the maximum of that column. So it's 53. What is the minimum? It's one, I suppose. Hmm. So that means we have only 53 weeks. So what Pandas is doing is that it's aggregating the weeks of different years, which means that it is aggregating the ratings of, let's say, the first week of 2019 with the ratings of the first week of 2019 and the ratings of the first week of 2020. So all those three weeks are going to be aggregated into one, and that is going to be Week one. Then we get week two for the second week of 2019, 2019, and 2020, and so on. In total, we had 53 weeks because that's how many weeks a year has. Well, normally it has 52 weeks as far as I know, but maybe one of these years it's probably a leap year, it has 53 weeks, I suppose. Anyway, you get the idea. This is not what we need. Let's try what the warning is suggesting DT so calendar. That week. Hm. It seems the maximum again is 53. So still, we are getting aggregated weeks. Therefore, the solution here is to use SDR f time, which means string from time. And that gets as argument some date time codes such as percentage Y, maybe a dash or that or space that is up to you. That is optional. But this is the code that you have to use if you want to extract the year. And then we extract the week number. Let's see what we get this time. Now we are talking. So this time, we get the year and we get the week. Therefore, we can distinguish between different rows. So week 13 of 2021 is now under this name. It's not just 13. Therefore, we'll have, again, 20 2013, 2019, 13, and so on. So we have unique names for weeks now. And that is what helped us to construct this datetime format. You could use other codes. So if you wanted a month, you'd use a lower. And then we would get the number of the month, April here and the week, the number of the week. As I told you, this is optional. So instead of the dash, you could use a space, and you get the space between the month and the week. Where can you find these codes? Well, you can just Google Python datetime format codes, and you'll see a list, a big list of what you can use. So let's use here dash and week number. Then what's next? Well, next is to group the data. So let's say weak average a new data frame equal to data dot group by week. So that column. And we want to extract the mean out of that. Let's see what we get. So it seems to be working. You see? Well, okay, Python is considering the first week, zero, zero, but it doesn't matter. I think it's okay. And so we have the average for every week. Again, don't forget that. The week column is actually the index. So that is the first week, second week, and so on. And the rating is the column. So let's do the plotting now. PLT dot plot. So we have to give an X and a Y. The X this time is going to be weak average dot index, so the week column and Data rating execute. I got this error. X and Y must have same first dimension, but have shapes that and that. So it seems like I am using columns from different data frames. So this is a week average data frame, which has 173 rows, and this is the other data frame which has 45,000 rows. So I meant to say day, sorry, week average. Wait, and this is the graph. Again, if you want to apply some sizing, you want to copy that and paste it in here. That basically modifies the figure object. And this is the graph. So average rating by week. Now, you see the labels here are smashed up with each other. And there are ways to fix that. But I would say it's not worth doing that here with Matt Plot Lee because if you really want to show your data to people, then you want to use a more modern plotting library, such as high charts, which we are going to use in the next videos. High charts will show a more intelligent graph now, which is user friendly and makes for great user experience and tries to show the information in a more efficient way. So I'll say this representation is sufficient for the purpose of using Matplot leap in Jupiter notebook. So we're just exploring data. Can see now we see a trend that the ratings are increasing by time. So maybe that was not very visible in the daily graph. So you see this graph here. This has the counts currently, but we can change that to mean execute the cell again, then execute the plotting cells again, and we can see the daily averages here, the week averages here. So I believe you agree with me that it's more easy to see the trend in this graph than in this graph. And that is the power of downsampling the data. In the next video, we are going to downsample the data even further, and we are going to show the average ratings by month. See you in the next video. 139. Downsampling and Plotting Average Ratings by Month: Hi. In this video, I'm going to show you how to create a plot showing the average rating by month. This is going to be a very short lecture because we already know how to do that. All we have to do is just copy that cell like that or you can also copy by pressing Escape and then CC. Hit the C key two times. Then here, you just go there and say V, and that will paste the cell so that you don't have to copy all the codes like that. But instead of copying the codes, you can copy the entire cell. And then we need to do some changes here, month here, timestamp, then instead of U, we have M. Instead of week, we have month. Instead of week here, we have month. This is fine. Then here we update the variable month average. Month average execute, and this is the monthly average. So I think it's getting better. You see that we see the difference more clearly now. And that is also because you see the range has changed over the graph since we have more aggregated data, so we have monthly averages now. That means there's not a big amplitude, a big difference between the highest value so you see that the highest value now is somewhere at 4.6 and the lowest value, which is somewhere at 4.3 or 4.35. That will make the heights and peaks more apparent to the user. Right, and that's about this video. In the next video, we are going to do something more different. We are going to look to create multiple lines in one single plot, and each line is going to represent the monthly average of ratings for each course. So far, we only had aggregated courses. So let's talk to you in the next video. 140. Average Ratings by Course by Month: Hi, welcome back. In this video, we are going to generate a plot containing different lines, and each line is going to represent the average rating by month for a particular course. So we have multiple courses. We're going to have one line for each course. Let's do that. Let's put a heading age three. This would be average rating by month by course. Right. This is how we do that. First of all, we need a month column in the data data frame. Now, I know that we did that here. We already have that month column, but I want to keep the code separate, so it doesn't harm if you do it again here just for consistency. So to say that this cell is doing that particular thing, so it's building a graph of multiple lines, and for that graph, we need this expression. So it's the same expression. I can just copy that and paste it in here. Right, we don't need to change anything there, so we just need to extract the month and let's check. So we have the month for each row. Since we are grouping by month, it makes sense to have that. Then we need to use the group by method to create a new data frame, which would be an aggregation. Now, just so that we compare it to compare it. Let's see what the previous month average data frame looks like. So again, that is what we had. This data frame is missing the information about the courses. So it's missing the course name information. You see here we have this column. We need to have that dimension somehow in our new aggregated data frame. So what we need to do here is something different. Again, we need to create a new variable. Let's call this a month average CRS maybe for course, to distinguish between that data frame and that month average month average CRS. This again will be a product by product of that data frame, using a group by method. But in this case, let me delete that so you can see the other code here to see the difference. In this case, we are going to have not only the month here in the list of columns to be used for the aggregation process, but we are also going to have, can you guess what course name? So by month by course, that's what we need. Let's apply now mean and see what we get so far. So this is a data frame. And basically, this one has actually two levels of indexes. It has the month and the course name. You can see that if you do that index. So you see it's a multi index. You see the month column and also a course name which doesn't show here, but it's there and as you saw it, you could see it in here. You see that these are in bold. These values, that means they are indexes. And this here is a column. So the columns are rating only, only one column. Now, this is not very useful yet because the way this is constructed is that we have a row here. So this is a group of rows. It starts here. So the first course, the second course, the third, fourth, fifth. And there's also some other courses here, which actually we can see them by applying here a slice. So let's see the first 20 records. Now we see the first 20 records in full, complete first day of sorry, first month of 2018, second month of 2018, and so on. That course has that rating for that month. That course has that average rating for that month and all the other courses. Then the same pattern, such as this one here is repeated over and over again for all the months. Now, to have this data in a better structure, what we would do is we would apply here unstack method to basically unstack this data frame and end up with this better structure. So now we have sort of a pivot table, so to say, we have the month here, first month, second month, third month, and each column now is representing a course so if you want to know, for example, the rating of the complete Python course built ten professional OOP apps for a particular month, let's say, this one, it's none because the course was not published yet in that date. But if you look at the end, let say -20 Then you'd see that from the first month of 2020, we have a rating for that course, an average rating, right? And so on, what can we do this data frame now? Well, we can plot it. But this time, we are going to use a different approach because we cannot use that plt dot plot since we have multiple, multiple columns. So this expects an X and a Y, but which one is the X? The X, of course, is month. We are clear about that. But which one is the Y? Is it that or that or that? So we have multiple columns. One way would be to write this plot function multiple times, or maybe create a loop that iterates through the data frame, but another easier way is to just point to average CRs dot plot and Villa, we have. Of course, it looks a mess, but let's improve it a bit. Since we used the plot function directly from the data frame, not from the PLT, then we can use fig size arguments in here. So let's say 253. And now it looks a bit better. Still not ideal, maybe we could increase that to eight. Okay. Now it's working. So there we have a legend that shows the color of each of the courses. Again, I'm not fan of this kind of graph, but when we use the High charts library with the web interface, this is going to look much better. Now, what if we use count here? We would get the graph correctly, but the legend would be a bit of a mess. That is because in the month average CRS data frame, We have not only the counts of the ratings, but we also have other counts of timestamps and things we don't need. You see that, for example, this course, 100 Python exercises one has the timestamp here. You see it's another level of columns. So all these belong to timestamp, right? The counts of timestamp. And then we have the counts of rating, starting from here and up to somewhere. We don't see all the columns because Jupiter is truncating them, but you get the idea, day and week. So how do we extract only the rating? Well, that is easy actually. I told you that group B, which starts in here and ends in here, group B returns a data frame. Now, out of that data frame, we extract only the rating. And problem solved. Now we get a clear graph showing the number of ratings left for each month of the year. So starting from the very beginning 2019 up to 2020, you see this pink line here, which is the new course, the complete Python course. It starts somewhere in 2021. So the first month of 2021. And of course, you can again, get the mean just like you did previously. But with mean, we again, get the same results since the mean method ignores those timestamp and those non numeric columns. So anyway, it drops them. But count does not drop them. It counts them up and gives us so much data. Right, I hope this was clear, and I'll talk to you later. See you. 141. What Day of the Week are People the Happiest: What day of the week are people the happiest? Can we answer that question by using Python and the data we have at hand right now? Well, I think, yes, we can do that, and that is the beauty of data analysis. If you are a bit creative, you can answer very interesting questions about your data. So in this video, we are going to find out together which day of the week are people the happiest? How do we do that? Well, by generating a graph. So how can we do that? Well, in my opinion, we can use the logic that if the average rating for all the courses, let's say, on Wednesdays, is the highest of the week, then we can see that people maybe in that day on Wednesdays are more positive. I'm sure we can tell that because we have so many data here. So thousands of ratings, and statistically, that, I think, gives us a lot of confidence in the outcome. What we need to do is we need to create a graph, which is going to have seven days in the horizontal axis, from Monday to Sunday and in the vertical axis, we're going to have the average for each day. That means we have to do a lot of data aggregation. Let's do that. What day are people the happiest? Now, we are going to use as always the data data frame. So where we have these ratings left at particular timestamps. So what do we need to extract? Well, the week day. Let's call it like that. Which is equal to Data, timestamp. So out of timestamp, we access the DT property, and out of that, we need SDR FT. And the day of the week. So if you want Sunday or Monday or Tuesday, that name of the day of the week can be extracted using the A format code. You can look that up on Google. I do that as well. It's impossible to remember everything. Now we can print out data again, and we see that we have a weekday. Column. So Friday, Friday, Friday is repeating over and over again, and we need to aggregate now to get the average for each weekday. So let's say week day average for the data frame that is going to contain the aggregated data. Again, group B is our saver. Mm. What do we use this time? Well, weekday. And then do mean. And let's see weekday average what we get. And that's it. Then all we have to do is, let me delete that. All we have to do is plt dot plot. The X axis would be week the average dot index, and Y axis would be week, the average, week day sorry, rating. Plot, this is the answer. I know the order is not as you would expect, but we can fix that. Either way, we can tell that Friday is quite different from the other days. So on Fridays, people leave a 4.455 average rating on a scale of one to five. And that makes sense. I think I also fall in that range, so I tend to be happier on Fridays. So end of the week and weekend is coming and so it makes sense. Now, how can we order this data? So we need to order the weekday column. Well, we can do that. Let me comment this out for a while. Week day average equal to week day average dot sort values by week day and then print out and see what week day average is. And you're going to see that this is not the order we would expect. That is happening, of course, because the index column, this one here, string values. So Friday, Monday, a day are all strings. Therefore, Python is ordering them in an alphabetic order. So Friday, first, Monday, and so on, they are strings because this method produces a string, weekday column. You see string from time. So timestamp was time, but we converted it to string. Now, there may be different workarounds to fix this. The one that comes to my mind is that we could add a week day number. Or simply the number. To the Data data frame, and out of that, again, you use string from time, but this time, we are going to use percentage lowercase W. And what that would give us is, let me show you Data now is this data frame and it has this day number. So now we have a number attached to each row besides the name of the weekday. That allows us now to sort the values by this day number column. Monday is the first one Friday is the fifth and so on. Let's do that. I'm going to delete that delta data frame from there, the printing, uncommon this and change that to day number. And here, week day average, delete, uncommon this, execute. We have this key error day number. Oh, because I forgot to add day number in here. Again, we have an error. Et's see where the error occurred. So these are the errors deep in the libraries, you see in MT plot Lip and this shows the error in our code. So it's in this line plt dot plot. And it says that value must be an incest of string or bytes, not a tuple. So let's try to troubleshoot the error here. I'm going to uncomment this and see what week day average is. So the problem here is that week day average that index returns a double index, which looks like this so it's a multi index. It contains weekday and day number. Therefore, the plot method will be confused, so it doesn't know which of these arrays has to plot along the X axis. So we need a way to extract only the columns. So the names of the weekdays. You can do that by using the get level values. That is a method that expects an argument. In this case, we can either input zero or one. Zero means we are extracting, we are accessing the first column of the multi index, and one would be the second column. So we need the first column. And that gives us those days, so the names of the days. Therefore, now we can make use of that in here so we can copy that expression. That is the array we want to plot along the X axis. So we put that in here. Execute, and this is the output. If we want to make the picture wider, we need to do plt figure size equal to a list of 253, it works well, or maybe a bit. Smaller. Yeah, this is better. So you have to find a good ratio between the width and the height. And again, we see that Friday is the day that has the highest average rating. And so that was about this video. Thanks a lot for following. I'll talk to you in the next videos. See you. 142. Other Types of Plots +: Hi. In this video, I'm going to give you some important information about different types of plots. We created multiple plots throughout the previous videos, and all of them had something in common. They were all line plots. So how do we go about using different types of graphs? Well, these line plots are generated by the plot method. But if you use the deer method to explore PLT, so PLT, you can see that you can also input down here. You see that you can also use other types of graphs. Not all of them are graphs. Some of them are properties that you give to the graph you are producing, but you'll see, for example, plot is somewhere here. So that was plot, and you can see, for example, we have bar, that one. If you change that to bar, we get these bars inside of the line. But this is not very good representation for this type of graph because the differences are very narrow between the ratings. So I would go for plot. Some of these types of plots, for example, Pi is not appropriate for this type of data. So if you try that Pi, you're going to get an error. Because if you use help, so let's say help PLT Pi. So a pie chart, you're going to see that Pi expects an X but not a Y. So how could we make use of a Pie chart with our data? Well, perhaps, so let me create a new entry here. We could perhaps make a pie chart, let's say, number of ratings by course, which would make sense. So this is what we could do. Let's say share the new data frame is equal to data that group B. We want to group by course name, by course, and then apply count. And that would give us this new data frame. So we are interested about the rating column. We see how many ratings each course has received in total. Now, if we don't want all these other data, we are only interested about the rating column. So in between group B and D count, we do rating, so we extract the rating column. Then that would give us that's serious. So we can use that. Let me create a new cell with PLT dot pi. So we said that Pi gets an X as argument. So that would be the share series. So the X is at least a series, a data frame column. So any type of array executes. And yeah, this is the Pi chart. But it doesn't have labels, so let's give it some labels. Was it like that? The argument. Labels? Yes. Currently, it's set to none, so the default value is none. So if you want to give labels, you'd say, share dot index. Index is the column with the names of each row. Execute. And yeah, this time, we get these labels for each slice of the pie. So you see that the Python mega course, for example, has the most number of ratings. Then comes the Python for beginners with examples, the brown slice in her, and so on, other courses as well. Now we do get a bunch of meta data here as well that this method produces. But as I've been saying, matplot leap is not the friendliest plotting library, so it's good for data exploration, but it's not very good for presentations to other viewers, to other readers, other users who want to see your visualizations. Now, that ends this video. And as I told you before, we are going to make all these graphs, every single one of them that you saw, including this one, let me change it back to plot. We are going to reproduce these graphs, but this time using a more modern web based library which plots the data in a browser and you can make a web app very easily so that you can give the URL your web app to your website to users and they can explore these graphs on their own interactively. The good news is that we are not going to do any more aggregations using group by our data are ready. We're just going to copy these and then use the plotting function of the new plotting library of high charts that we are going to use in the next videos. So thanks a lot for following this series. I'll talk to you in the next one. See you. 143. App 4 (Part 2): Data Analysis and Visualization with In-Browser Interactive Plots: Welcome to a new series of videos. In these videos, we are going to learn how to create interactive charts with Python. Let me show you the exo charts that we are going to create throughout these videos. This will be the first chart. You see these are interactive. For example, when we hover the mouse over the graph, we get these pop ups looking at the exact value at that point where the cursor is pointed. That will be average rating by day. Then we have average rating by week by month by month by course, for multiple courses. Then we have this cool graph. It's a stream graph. Again, this is average ratings by month by course, but shown in a different plot. Then we have when are people the happiest. Then lastly, we have this Pie chart, which, again, is interactive. And it's much better looking than the other charts that we built with Matt Plot lip. So these charts are built with high charts. Now, High Charts is a JavaScript ploting library, but we can use high charts in Python through Just Pi. And Just Pi is a web framework for Python. It is quite new, so chances are that you haven't heard about it. And so Juspi is a web framework like FAS, but Juspi has a very crucial advantage. The advantage of Juspi is that you don't have to write any HTML, JavaScript or CSS. You can create complete apps, complete modern looking websites with Jus Pi only. So you're going to shoot 2 stones with one bird. I mean, one bird with 2 stones or two birds with 1 stone. You get the idea. So you're going to learn both Jpi and also high charts. That's what I meant. And here's the plan. In the next video, I'm going to show you how to create a one page Pi website, which contains just a title and a paragraph with text. So a simple webpage. Then in the video after that, we are going to expand that website by adding a high chart graph to the webpage. In other words, in the next two videos, you are going to learn both how to create a Just By webapp and also how to add high charts graph to Justpy WebApp. Then in the videos after those two videos, we are going to learn how to create other charts. So the ones that I showed you here and which are the charts that we built that we created on Jupiter with Mat Plot Lip. So we're going to create every single one of them. So get ready, and I'll talk to you in the next video. 144. Making a Simple Web App: Hello. In this video, you are going to learn how to create a simple web app with the Just Spy web framework. I'm going to use Visual Studio code to write the web app. So Jupiter would not work here. So I suggest you to use an IDE such as Visual Studio code or whatever IDE or text editor that you are using. So I've started Visual Studio code in here. I'm going to go to File Open. In Visual Studio code and then go to the folder where my reviews that CSV file is located and press on open, and that will create a new Visual Studio code, project directory, pointing to that folder where the reviews that CSV file is. We don't need to reviews that CSV for now because in this video, we are going to just create the web app. So let's create a Python file. I'm going to name it zero simple app dot PY. So I'm going to create multiple web apps, and I'm using 01234 now. In the names of these files. To use Juspy, we need to have Justpy installed. So I'm using 3.9 Python 3.9 now, and I'm going to go to terminal New Terminal, and here I will use PIP 3.9 since I'm using Python 3.9, Install just PY. All right. That was successful. So I got no errors. I got this message that it was already installed. But anyway, I hope you were successful too with the installation. Then what we need to do is just import. Pi. A good practice is to import it as JP because you are going to look at the documentation of Just Pi, and all the examples are using this JP name. So it's a good idea to be consistent with the documentation. Now, every By app will have a main object that is known as a Quasar page. So that is the web page, basically. And that web page may contain different elements. So it may contain, for example, on page one, heading or a paragraph or maybe a table. So all these elements will be added to that Quasar page to the web page. Why is it called Quasar? Well, because Jus Pi uses the Quasar framework, which is basically a framework that is not related to Python. It's a framework built with JavaScript, but Jus Pi is using that framework and we can use that framework through Python. So let me create a Quasar page. What we do first is we create an app function. You can name it wherever you like, but basically the idea is that this app will return that Quasar page. So inside the function, we create a variable which is equal to Jp quasar page. So Q, P. That is a class that we are instantiating here. So we are creating a quasar page instance object instance, this function then should return that quasar page instance. And in between is where we write the elements that this page is going to contain. So let's create a variable for each element. Let's create a heading. So a heading is basically text, but with a very big font size. And we do JP, so we point to that dot QD, so QDV. It's basically a division if you are familiar with HTML. It's a division, but it's a Quasar division. So it has some styling from Quasar which make it look modern and it also allows you to style it very easily as you're going to see in just a bit. As the first argument, we should pass where it belongs. Of course, that belongs to WP that variable, which I named WP to stand for web page, webpage. That belongs to that. Then other arguments that QD gets is the text. What text do we want to display there? As a string, let's say, analysis of course reviews. Let's also add a paragraph. Let's call this P one is equal to p dot QDV again. We always use QDV and A, it belongs to WP again. The text this time. So let's write like a description of the webpage, these graphs represent course review. Course review analysis. That would be a very minimalistic web app. But if we are on this now, nothing is going to happen because we create the function, but no instance is calling that function, so we are not calling it anywhere. So let's do something that we call that function. We can use Pi from JP. So Jus Pi is a function and it expects as input, a function that returns a quasar page, which is this function here. So you can just write app without calling the app function. So Pi, this function will take care of calling this function. Right. If we execute it now, you should see this message here that Just By is ready to go at this address with this 8,000 port number. If you press Control and click or Command and then click, that should open your default browser. And this is the web app, so it's working. Now, you would expect that this would be in a bigger font. That didn't happen because we haven't added any style to any of these divs. So these divisions are just plain text. To add style to elements, you can add a classes argument to any Q div element, and that is equal to a string. So how can we make this div big? Well, I can show you, of course, but I want to show you the way how you can find any type of styling that you can use with Pi. So what you have to do is just search for Quasar style. And then go to the first result. Understyle and identity, you're going to see the attributes that you can change for the page elements, such as the div element that we have at hand now. So we are concerned about topography. If you click there, you're going to see examples here. So if you want to make the text this big, you want to use Text H one. So let's try that. Copy it and edit here. Text H one. Now, something you need to know if you're using Visual Studio code is that if you run the code with this button again, while the code is running, nothing is going to happen. So the program will just freeze and if you go back to local host, you see that the old app is still running. So what you have to do is you need to go here and press Control C to stop the current process and then go to that button and run it again. Then you're going to see that the app updates and we have these big phones now. So let's look again, Quasar style under style and identity. So we were talking about typography. You also have other examples here what you can change. And so if you want to add another property, let's say, you want to put this text to the center, you want to use text to write. So you copy that. Go to your app, make a space, and put paste the other style property. Stop the code, run again. Reload the page. And you see that the text went to the right. Yeah, so I meant to make it center. So let's say text center. Stop run again. We get this pop up sometime that it texts that the app change, so we can press Okay, and that will reload the page. So this is what I was expecting. If you want some padding, so if you want this text to be not so close to the upper bound of the webpage, then you may want to look at spacing. So in spacing, you're going to see down here that you have all these options. So for example, if you want the padding on top to be extra small, you use that text. If you want to have a padding of all, so all around the text, you want to have some space here, space between the text and the upper bound and space between this text and the next element, which would be this one here. Then you want to go to maybe padding all medium, so you want to copy that and add it there. So make a space. Rerun, reload. And you see that now we had some more space between that and that there. The last change I want to make is I want to make the text a bit smaller. Control C, run again, go here, reload, and now it looks better. That is how you make just by webapps. Note that the order you create these elements matters. So you see that analysis, of course, reviews is on top. Of the other element here. So if you want to keep adding elements down below here, you want to respect the order. So you want to add more elements here and always don't forget that you always need to connect that element to the webpage. Now, that was how to create a simple web page. But Q DFs are not the only element we can use. We can also use high chart element, which is a plot that we can add to our user page. Let's do that in the next video. See you. 145. Making a Data Visualisation Web App: Hello, welcome back. In the previous video, we made an app with Just Pi. This app contained two components, so they are referred to as components in Jus Pi. So this component here, Q Div and another component Q Div, they both are added to the main component, which is the Quasar page. In this lecture, we are going to add a third component, which is going to be a high chart graph, which is still a component of Just Pi. So let's do this step by step. I am going to create a new Pythople where I'll be writing this new app. So let's name it average rating day. So average rating by day that's PY. I'm just going to copy this code because we need that and space it here. And now we just need to add the high charts component. So let's take things step by step. The very first step we want to go through is we want to find the proper graph that we need there is a very good way to do that. We can go to the high charts documentation and look at the examples at the graph examples that they show on that page, and then we can pick one of them. Let's do that. Let's choose a graph that we need. Go to your browser and just look for high charts docs on Google. You'll find this page High Charts documentation. So High Charts is also a JavaScript library to produce plots. So just like Quasar, Quasar was a JavaScript library. It's unrelated to high charts. And Python is getting these two libraries, these two frameworks together, which is really great for us Python programmers to use both these two modern JavaScript libraries from Python. So here we are in the high charts documentation, and we want to go to chart and Series types. And here you're going to see that we have different types of charts. So in our case, I think a spline chart would be appropriate. So if you go and click over Spline chart, you're going to see this example here. It's about temperature by altitude. It has this temperature axis horizontally and this altitude axis vertically. Now, each graph provides the code, the JavaScript code that produces that particular graph, and you can see that you can access it either from the JSFiddle or code pen, which are basically two online code editors. If you click JSFiddle, it's going to open up the code that produces that graph. And every graph has its own code. So if you go to stream graph, you go to JS v again, it's going to show you the code for that stream graph. Anyway, let's go back. So this is the graph we are interested about, and here is the code that produces that graph. So you can also see a live version of the graph here. If you change something here, it will produce that graph. But I'm not saying that you need to learn Javascript. All we need to do is you need to copy the code that starts after coma of this container here. So that means from this curly bracket, you need to select it. And go down down until you see this semi column and this round parenthesis, and you want to copy up to this curly bracket. So you want to include that curly bracket. So press Control C or go there and copy it and then go to Python. And what we need to do is we want to create a string. Let's create a variable. Let's say chart definition is equal to a string. I'm going to use triple quotes. So six quotes, and I'm going to split them. So three quotes here, three quotes in here. Inside here, I'm going to paste all that code. So again, you have to be very careful here. This code starts with this curly bracket, and then it goes chart and so on, and it ends with this curly bracket. Now, before I explain you what I'm doing here, let me first make it work quickly, and then I come back to the code and explain you what's going on in here. So once you have the code definition, that's one, you want to go here and let's say HC for high charts, JP, C charts. So that is the component we want to use. A equal to WP so the standards argument. And now, this high charts component expects an options argument, which is equal to this variable, which contains the JavaScript code chart Def in my case. That's it. Now, if I execute this code, you see the app is running, Command click or Control click, and this is the web app with the graph inside. So this was the first step getting the code from the high charge documentation and pasting the code inside your Python program. Now, let me explain you the first step what we just did. So as I explained to you, High charts is a JavaScript library. Therefore, this here is JavaScript code. But in this case, this is JSN. So JavaScript uses JSON and JSON format is a familiar format for Python. So it looks like a dictionary. You can see it starts with this curly bracket, and then you have this key so even though it's a string, now, currently, it's a Python string, what happens when we do this here is that Juspi will convert that into a Python dictionary. So a real object that Python can read and manipulate. So Juspi will process this dictionary, and it will render it as a graph on the web page. I can prove you that Python has successfully read this string as a dictionary by printing out so print HC dot options. So options, because we passed it here as an argument, this will become an attribute of HC and we can access it like that. So there I'll print out the dictionary, and down here, I'll print out also the type of that HC option, so you can see what type it is, and console C to interrupt the current instance of the app run again, and nothing will happen now because I haven't loaded any instance of the page yet. So if I go to the page and then I go back here, you're going to see that something was printed out since when I loaded the page, this app function is executed, and therefore, these two lines are executed. So let's see. This is the dictionary, right? It starts there, it ends here. It's the same dictionary that we paste it here as a string. Also see that the type is not exactly a dictionary. It's a different type of dictionary that it is like a Python dictionary plus. It allows us to access the dictionary keys using a dot notation. So for example, let me show you what that means. If you go here to hc dot Options and you say dot again, you can access all the keys of this dictionary. For example, let's say we want to change the title this title here, right? So we can access that title key using dot title. And then this title also has a dictionary on its own. We can access the text of the title using the dot notation again. So let me do that title text, right? Title text is a hierarchy. So let me stop the app instance and run again. Go and reload the page and see what we get printed out this time. You see, we got access to the value of that text key, which was that title. Now, that allows us to change the title to something else like average rating by day. So let me stop the instance, run again, reload. And you see that the title has changed to average rating by day. What I'm trying to get to is that you can change everything from this graph, anything that you like, anything that you need to change from this graph. And, of course, our first interest is to change the data of this graph because currently, you see that the graph has this serious key. And this series key has a name, temperature, and the data. These are the data that are being plotted on the graph. So you see a zero, 15, ten -50. So you see, for example, 15 is a temperature, zero is a kilometers. And then we have, as I said, ten -50. So at 10 kilometers altitude at the temperature is around -50. So those are the data. Let's change those data to something else. To do that, we need to get access to H C but options dot series. Right, series. And Series is a list. So you have to be very careful here. You have to understand Python data structures, and this is an excellent, actually excellent practice to really understand and level up your skills with Python data structures such as lists and dictionaries. So series is a key and the value of this key is a list. And that list is made of a dictionary. So it has only one item. This list and that item is the dictionary. Then this dictionary has two keys, a name key, and a data key. The name key has as value temperature. The data key has as value this list. It's one list with multiple values as lists as items. It's a list of lists. So the second list, the third list, and so on. And so far, this gives us this list, right. And out of that list, we want the first item. So that will be item with index zero, right. So which is the dictionary. That means this far, we have a dictionary. Out of the dictionary, we want that data. So that now is that list. We have access to that list and we can change that. We can set a new value, a new list to that list. For example, let me create some dummy data, three, four, six, 789. So we have three points. Let me stop the app, run again. R load, and this is a new graph. So again, the data were three, four, six, seven, eight, nine, three, four, so three is the X. So this is reverse graph, actually. So three is Y, four is the X. If you want to reverse this graph, if you don't feel comfortable with that, you can go here and change that to falls. And you could also change this data directly here without having to change them here through the dictionary. But later on, we are going to inject data frames, so columns from data frames. And this is a proper way to do that. So this one here because it allows us to work with a dictionary instead of working with a string. And the string is not a data structure designed to hold data inside. But anyway, for simple things like that, you can just change the values directly here. So inverted, I'll set it to folds and Stop and run, reload. And now the graph is different. So you see the altitude is down here. The temperature is in the Y axis now. All right, so I manually type down some data here, but this is not what real life looks like. So in real life, you'll not have data in this format. Usually, you have them in a data frame in a CSV file, just like we have them in our app. So we have the data in reviews that CSV. And so the format will be slightly different. Usually, we're going to have something like an X array for the X axis, we should look, let's say, three, six and eight, and then we have Y equal to four, seven and nine. So not like that. Therefore, our goal is to turn those two lists into this list. How do we do that? We do that using the zip object, which basically produces that kind of list. So in the formats with pairs of lists. That expects X and Y. So two lists. However, this is not a list yet. This is a zip object. I can show you that in a Python shell. So let's say we have this list and we have that list. And Zp XY is going to still be a zip object. You want to convert that zip object into a list using the list function. So X and Y. Now we get that list that we were expecting. Therefore, we can get that list and use it there. Now, if I go to the other terminal here, I stop the app, run it again. Reload, and we still get the same graph with those data. Now, what if these are coming from a data frame? So that brings us to our app with our reviews data. So let me go over to the code we were working on on Jupiter. Which is this one in here. So we load the data frame with that code. I'm going to copy that and paste it here on top after importing Jus Pi, right? We have this data data frame now. And what else did we have to calculate the average rating? Yeah, we had this day average data frame, which was an aggregated version of the data data frame. So I'm going to copy these two lines, and I'm going to paste them in here. So day average is the data frame we are interested about, and it has an index, which is going to be the date and a rating column which has the average ratings for every day. So you can just to refresh your memory, it looks like this. Right. Now, instead of X, we would have d average, the data frame dot index. So that will be used as the X axis. And then for Y we would have day average rating. So that column. So these are treated as two lists by ZIP, and ZIP then we pair them up, so it will create a pair of date and rating. So for example, it will on the background, it will look like a list of lists, as I explained to you. So the first date would be like 2020 133, and the rating 4.51, let's say, answer one, the next date and you get the idea. So let's try this out. It will not work, and I'll tell you why. So as I told you, we get an empty graph and no errors. The reason this doesn't work is that high charts considers the date. So those kinds of data, it considers them as categories, types of data, not numbers. And in that case, you need to provide this data in another way. That is through options X axis dot categories. So what is that? Well, X axis is actually here. And we are doing X axis dot categories. Now, you don't see a key here, but we are creating that key. That is going to be equal to list the average dot index. So we are converting that to a list and providing that list to that categories. This is a list of dates. And then for Delta, all we have to do is convert to a list the rating column. Let me stop the script and see what we will get this time. Refresh and boom, we get the graph that we were expecting. The graph is interactive, but you see that we have some labels here and some titles for the axis, which are from the old example, so altitude and temperature, but we can change them. So I would suggest you can change them directly in the JavaScript code. So you can change the text of the title from here. You can change the subtitle from there. So I believe that is easy to do in the code. Just to give you a quick summary, what we did is we load the data frame here that we need. So day average is the data frame that contains our data. Then here we have the high charts JavaScript code. Then we have the function that renders the webpage. We have the webpage component. We have these two components, normal components, text, QD. And then we have the high charts component, which contains now this chart D JSON as a dictionary. So we can access that dictionary through options, since that is stored in options. So now HC options is the dictionary, and therefore we can access then properties from that dictionary and change them as we wish. And the most important use of that is to set the data. So you saw that for data that contain categories, not numbers, you can use that X axis and set that category's property to a list, which is a list of dates. And then data is equal to a simple list of ratings. This is the app. Thanks for following. And this was a long video, but the next apps are going to take much less time because you now know the process and with some practice, you'll be able to make any graph you like. Thank you. 146. Changing Graph Labels in the web App: Hi, welcome back. In the previous video, we built this time series graph of average ratings shown on a daily basis. Now you see that we have some unwanted labels here, such as temperature here, we have kilometers as an ending of the X axis labels. So I'm going to quickly change this in my code. Now, you can either do that through Python by using that dictionary dot notation, or for these things, I would suggest you just go through the JavaScript code directly. So for example, we're talking about the X axis, and here we have altitude. So the X axis should actually be date date. Then we have these labels, the format of the X axis labels. So it has this kilometer ending, the one that you see in here kilometer. If you want something else, just write it down here. Otherwise, just delete it and leave the value as it is. Don't delete these kinds of Javascript placeholders. You can also change the range description, even though this doesn't show anywhere. So I'll move on with temperature. So that is why axis where we have the average rating. Where else we have this Celsius degree symbol here. I'm going to delete that And we have this temperature name here, which is actually the name we get here in the pop up window. So temperature that corresponds to that. So you may say again here, average rating, and then control C, run again. And let's see the changes. So reload. Yeah, average rating here, dates here, average rating there. We still see this kilometer in the pop up. You see 506 kilometer. That is here in the tool tip. So you want to delete that and delete that as well. The tool tip has this header format, which is a series name, so the temperature, and it was temperature before now it's averagere rating. So that is series dot name. And we also have point dot X. So it's going to show the X value. In our case, that is the number, so the index column, which is a number from zero up to some number. So the number of the row, and that is the average rating that you see there. So we're run again and this time, everything should be fine. And that ends this video. I'll talk to you in the next one. 147. Adding a Time-Series Graph to the Web App: Hello, welcome back. In the previous videos, we build this daily graph of average ratings. In this video, we are going to build the same graph but on a weekly basis. Now, this is going to be a short video because I'm not going to explain the code because I already did that, so you'll be able to easily understand what I'm doing. So let me go back to Visual Studio code, and I will create a new file. I'm going to name this F for average a Terrett for rating and Week. So that is number two. And what I usually do when I build these graphs is I go to that template of spy and paste it here, and then inside here, then I create a new high charts component which belong to WP and as options, it has this chart de variable, which is going to be a variable in here. It's going to be a multi line string enclosed in quotes. So here now, I'm going to find an example from high charts. So I'm going to use the spline again for this weekly chart because I think that's the most appropriate chart type for this kind of analysis for this kind of visualizations. So I will click over to JS Fiddle and that will show me the JavaScript code, which is this one in here. I can copy all that and go to Python and paste it there and then of course, delete that part. It starts with the first curly bracket before chart, and then it ends with a curly bracket, so I'll delete the semi column th parenthesis. Options points to that doc string. Before I apply my own data, I first try out this code to see if it's working, but first I need to stop the current process with Control C and run Go to buy reload. Yeah, it's working. Next, I want to import pandas. So since I was doing the analysis on Jupiter already, I can just copy and paste these lines. Paste them there. We don't need Mt lips I can delete that. This our data frame. Now we need to do some analysis on this data. So go back to Jupiter and find the weekly analysis so that one in there. Week average is the data we need. So paste them below the original data frame and we should have this week average now. Now, week average is going to have as index column the weeks. So here and week that is going to be week average dot index. And there will also be a rating column in the week average data frame. So let's use those two columns to plot the data. So we should be accessing Hc dot options dot X axis categories for categorical data such as date. So that would be weak average dot index, but in the form of a list. So we have to convert it into a list for just by to recognize it. And then HC Options that's serious. That data. So which means series zero gives us this first item, which is a dictionary. So we have the dictionary here, and then we access the data key from that dictionary. So that will give us actually the value of that key, which is this list. And we replace that list with another list, which is a weak average rating. That should do it. So stop control C Re run, reload. This is our graph. It looks weird because we have to reverse it. Actually, it's originally reversed. So we should say falls as a value of inverted Control C, and re run. Reload. And yeah, this is it. I'm not going to waste your time and change all these labels as I did in the previous video. So I already did that. Therefore, this is enough for this video. Thanks for following. I'll tell you later. 148. Multiple Time-Series Plots: Hi, welcome back. In this video, we are going to create an average rating by month by course graph. As you may know, we created that graph already bought using Jupiter and Matplot Lib. So it looked like this. The idea is that we're going to have the month in the horizontal axis and averagere ratings on the vertical axis, and we're going to have multiple graphs in that plot area, each representing a course in our dataset. And as you may know already, a good way to create graphs using B and high charts is to go to the higchart.com website. So you go under charts and series types and we find a graph that would be a good representative of our data. So I took a look in these examples and I found that I would like to use Area Spline chart, which looks like this. You see that this has multiple lines, so two, in this case, and it has this X axis with categorical data. So it's not numbers, it's Monday, Tuesday, Wednesday, and so on. And we have this number Y axis, so fruit units. And it represents the average fruit consumption during one week for John and Jane. In our case, we are going to change this graph and have six or seven lines. I'm not sure how many courses there are. So one line for each course showing the average ratings a long time over the months. Before we copy the codes, let's first prepare the environment. Create the script and create the by app and so on. I'm going to name this four average rating. This would be, let's say course month. So average rating by course by month that PY. You see that is different from average rating month. This is average rating by course by month. Then I'm going to copy this template of J Pi. Copy there. HC will be the high charts component, which belongs to WP, and options is going to be a usually chart definition, which has to be a variable somewhere here. Is equal to a string, a multiline string. So let us copy that JavaScript code. So this one in here, I'm going to copy all of that, paste it in there, and then just before chart, we leave that curly bracket before chart here. We leave that and delete the semi column and the parenthesis. And now we are ready to replace the data with our data. But what I suggest you do first is to try out this example to see if this is working right now without changing the data with your own data. What I would like to do now is try to run this and then visit the URL, and you're going to see an error. So Jason Decode error, unknown identifier high charts. This happens because of this line. Python cannot recognize this expression here because this is JavaScript. So you want to delete that and only leave this string here, the color of background color. And now, if I stop the script and run again, And reload the page, we should see the example just like we got it from the high Chart's website. Now, these two graphs are area splines. But if you want to change them to spline, you want to go over to your code and change that area spline to spline, stop the script, run again. And reload. And this is the output. Now we are ready to inject our own data into the data. So for that, we want to go over to Jupiter where we have our analysis ready. Copy that code paste it there, and we also need to do the aggregations necessary for extracting the month, the courses by month, which is this code here, and that gives us this data frame. Now, let's refresh our memory how the data frame looked like. So you can either print them in here and execute the script, reload the page and see what you got printed out in the terminal, or you can see the output from Jupiter. So whatever you prefer, I'm just going to execute the script here. And so we get the data frame printed out even before we load the web app because it printed out because the web app is inside the function, so this is just in the global namespace, in the global scope. So when the script is executed, these are executed. If this was inside the function here, it would only be executed when we load the page. And this is the data frame. So it has this month index, and it has different columns. So this is first column. Then we have more columns, which we don't see in here. And then the last column is this and the values of each column. So the name of a column, the values of that column, which are the average ratings. And we have one month for each row. So this is July of 2019, August 2019, January 2021. So index columns. Let's see now how do we inject those data into these data? So we see that XXIs has these categories with these weekdays. So we can do the same thing now. Down here, we say hc dot options dot XXI. So XXs is the key of the main dictionary. So it's directly exposed in the first level. So chart title, legend axis. And then we have the second level. So category is part of axis. Therefore, we can access it like so so categories is a list, as you can see here. Therefore, we need to replace it with a list list a month average CRS. So that is our data frame dot index. So that column in there, 20185, 20186 and so one. Right. That was the easy part. Now comes the data. So what you need to do is you need to understand the structure of the data. That is the very important first step. So series is a first level key. Therefore, we can say Hc options, that's series, right. So this will give us that list. Then that list has how many items does it have? I see a dictionary from there up to here. That's a dictionary that has this name John pair of key and value. So name is the key, John is value. Then we have this other key data and a list, and the dictionary ends there. And then we have the other dictionary. So it's Jane How and these are the data for Jane. The list is made of dictionary, and each dictionary represents a line in the chart. So that's for Jane and that's for John. Therefore, what we need to do is we need to have here. So that would be the name of a course. Let's say the first course would be 100 Python exercises, and so on, the entire title. And then data would contain a list of average ratings for that particular course. So that one, that one, that one, and so on. And then we would have to repeat that process for each of the six or seven courses that we have here. How do we do that? Well, you could do that manually. Like maybe you could inject so from series, you'd say the first plot, so that would give you the first dictionary. That expression is the first dictionary. Then we could access name and replace that to maybe the month average CRS dot columns. So that would be the first column and so on. That would be okay, but it's not an automatic process. So when you do manual work, that is a sign that you're not doing programming the right way. What we need to do instead, is we need to create this entire list dynamically. And this is a very, very crucial point now in using high charts, but also in knowing how to manipulate data structures in Python. So this is an excellent practice. I'm very glad this came out. Such a great practice for you. So let me show you how you can construct this list out of this data frame. So before we do that, before we assign the list, we want to construct the list. So let's name this HC underscore Delta. And that is equal to. So we need to create a list. So that is a list. Therefore, we write square brackets. The list is made of dictionaries. Therefore, we write curly brackets. And then inside each dictionary, we have a name key. We always have that name key and a variable for that name key. Why I'm saying variable? Well, because name is always name, so it's a constant. That's why I'm hard coding that we should always have name there. But the value of name is a variable, so it's changing every time. And then what else? We have that pair, okay. Inside the dictionary, that dictionary. So that dictionary has another pair. So data and the list. So let's write that. Como Data, the string, a column, and we have a list. That list is basically representative of each of the plots, each of the seven plots that we are going to have for each course. So which means that list is going to be these ratings. For example, we're going to have the first list being the first column, for example, for Python exercises one for that course, this column as a list in there and then the other column. After that course, the next and the next and the next. So one column for each course, and V one is going to be replaced by the title of the column. So before I write the expression inside this list, I want to finish first the upper list comprehension because we have two list comprehensions here. We have the first level one, so let's call it the upper level. Here we are constructing dictionaries. So it's a list made of dictionaries so that means we should say here for V one in month average CRS tat columns. So what that is is a list containing seven strings, one string for each course title. So it's going to be a list containing 100 Python exercises one, evaluate and improve your skills, then the other title of the other course, and so on, it's a list of these titles. What we're doing is we are injecting here a title, the first title of that list in the first iteration, then the next title of that month average CRS columns list in the next iteration. And so one, we're going to have seven iterations or six, whatever is the number of courses that we right. But then, inside here, we have a nested iteration, a nested list comprehension, sorry, which is this one here. And that will be, again, let's write another variable, such as V two for V two in month average CRS. Hm. So what is this going to be? Well, it has to be this column, right? So which one is this column? What's the name of this column? Well, for this course is that is the name of the column. So here we need to write down the name of the column. You see, this is a Pandas syntax. So you write the name of the column, but we have different column names. So what we enter here then is V one. Because V one is going to be the current title in the upper level list comprehension. So basically what Python will do is, while it is iterating the first title, it's going to stop in that upper level first iteration, and it's going to iterate through that particular column through these ratings for 100 Python exercises one. And it will construct that list once it finishes with all these numbers, it constructs that list, then it goes the other to the second iteration in the first level iteration. In the second iteration of the other columns, which is going to be the next course. And so on, I hope it's clear. Right, so what's left to do is we need to assign this new list, so to inject it to our data because we created it, but we haven't connected it to HC. So it's just a variable floating there in our script, no connections to the other parts. So what we need to do is we said that that one, that list is that list. So we need to assign it to Series, right? Ct options dot Series, equal to HC data. Right. Now I'm going to stop the script and run and visit the app. And this is the output. Here is X axis with the month, and this is our rating from 2.5 up to 5.5. The maximum is somewhere in here. So you can over your mouse there and you see the ratings for each course, right? The legend here is floating. So if you want to change that, you can go back to your code and locate the legends here. So you have some parameters here which you can experiment with. But if I set floating to falls, That should change the view of the graph. So I think this is more clear. Now, I wouldn't agree that this type of graph is the best representation for these kind of data because we have multiple lines here, but they are so close to each other. So there's no much variations between one course and the other. I think these splines would be more representative if we had instead of averages, we have the count of the reviews of the ratings left for each course, which means we have to go to the processing section and say here, count instead of mean. And let me try that. Hmm. So yeah, it looks better, I think. We have more variation, more difference between this plot and the other ones. Although the other ones are still not as visible, since this plot here is taking a lot of the range of Y axis range. Therefore, what I'm going to do next in the next video is I'm going to use another type of graph to represent the same exact same data. Average ratings by course, by month, but using a stream graph. I'll talk to you in the next video. 149. Creating Multiple Time-Series Streamgraphs: Hi, welcome back. In this video, we are going to create this stream graph. So you can find it on the hichart.com website under chart and series types. So go down to Stream graph. In the X axis of this graph in this example, we have the years, so it's a time X axis categorical data. On the Y axis, we have the number of medals won by athletes, and each color represents a country. So each country had a particular number of medals won by its athletes for a particular year. Now we're going to have the same graph, you get the idea. We have the months along the X axis and each color we represent a course and then we can have either the average ratings or the number of ratings in the Y axis. Before we copy the JavaScript code of this graph, let's go and prepare our environment. I'm going to duplicate this by copying it and just press Control V to paste it. I duplicate it and I'm going to rename it to something else five. Let's name it stream. Right. Then go to the file that we have just created. And all we have to change from here is this chart definition, delete that and go here, select all that, Control A, Control C, copy, go here, Control V to paste it, and don't forget to remove the unneeded character, so the semiclumn the parenthesis, and up here we need charts and we need the curly parenthesis before charts. So everything before that curly bracket is deleted, like that. So let's take a look now at this data. Yeah, how the data are constructed. So series is a list. It's a big list containing multiple dictionaries. So for example, this is the first dictionary. It starts here. It ends in here. And it's made of this pair of key and values and name and the name of the country, which will be replaced by the name of a course. And we have data, which is this list. And so these dictionaries then are repeated over and over again with different data. That means we don't have to change our code down here. So we had this code. We built it already in the previous video. So that should be fine. Let's try to execute it. We're going to get an error, and we're going to fix it. So stop the current process if there is a process running. Make sure you are executing the new file that we created. So press Run. So this is the error. And when you get this Jason decode error, that means it's about that JavaScript code that we have. So we want to go to the codes, and you see that it's about colors and unknown identifier because what we have here is these colors, and we need to delete those. And you can delete the entire colors. So from there to here, including the comma, because Python is not being able to use that colors. So delete that, and that is not going to change any output. And let me show you. We have another one Peto. Yeah, so it's here. So we have this kind of JavaScript syntax that Python is not able to recognize. So what you could do is, since we are replacing this anyway, sorry, you can delete all the values of the categories list and leave categories an empty list. So just like that categories. So categories is being replaced, as you know, down here through this expression. Let me stop again and run. This time seems to be working. So these are actually the number of ratings left for each course, so it shows you the difference between this course, the Python mega course and the other courses. And this is something interesting here. So you see this new course has just been launched not long ago sometime in January 20 21st. So the complete Python course built ten professional OP apps, and high charts is very intelligent to adjust it inside this stream graph. Now, you may want to change these labels so you can easily find them. You can locate them where they are here so I can perform a search Germany, which is this text here. So it's part of annotations. You see, you could say, for example, for example, course launched or Python got popular. Right. If I stop it and re run. We should see these labels updated. You can also update their location. So for example, you see, with the first annotation, it's at X 5.5, y 30. So X 5.5. So zero here, one, two, three, four, five, six, so it's 5-6. 5.5 30 along the Y axis. So 30 should be somewhere in here. So you get the idea. That concludes this video, and I'll talk to you in the next ones. 150. Adding a Pie Chart to the Web App +: Hello. In this video, we are going to create a pie chart, just like the one you're looking at. So you can find this from pchart.com, go to Chart and Series types and go to Phart. This one here shows the percentage of users for the major Internet browsers. For example, Chrome has the majority. You see these big slice here and each slice is associated with the percentage. In our case, what we're going to have is we did this analysis earlier, so we have this data. For each course, we have a number of rating left for that course. Therefore, we're going to end up with something like this, but interactive, as you can see in here. Let's go and prepare our environment. So I'm going to create a new file ratings by course. It's a pi. And as usual, I'll use this template, this Pi template and then add a high chart component which belonged to WP and will render this JavaScript code, which we have to paste in here. So inside here goes the code of this chart. So that one in there. Control A, copy, and paste it there, and don't forget to delete the semi column the parenthesis and on top here, delete everything that is before that curly bracket. I'd like to try out the code before I make any changes. But I have this error here. There are four codes. I have to remove one and then run And so we get the pie chart visualized correctly. Next, I want to get that code pasted on top here. And also, we want to have this aggregation of the data frame where we are basically counting how many ratings are for each course. So course name rating. Count that. Right. Then next, we have to look at the structure of the data. So as you can see, this is a big list with dictionaries. So here is the first dictionary, but be careful here. From what I see, what we have here is this dictionary which has this key and value, this key and value, and then this key and that value, which is a list. So it ends in here. Therefore, this time, what we need to do is access hc dot options dot serious dot data. So unlike the other times when we did hc options dot series, because the data were directly after Series. Series was the list. But this time, Series has a data key, and that data key contains the actual data, which is made of dictionaries. So the first dictionary with name and Y, the second dictionary with name and why again. The first dictionary also has these other properties such as sliced through and selected through, which indicates that Uh, this chrome is slice. You see, it's separated by the other slices of the pie. So that's for chrome. The other ones don't have those properties, which is fine. So I'm just going to leave it like that. But every one of them has a name and a Y. Therefore, this will be equal to something, and that something is something we need to construct now. So HC data will be that that's a list. It's a list of dictionaries, right. A list of dictionaries which have a name equal to let's find a name for a variable V one, right? And then so name and Y, the label of the other value is Y. Let's have a V two variable. So since these always change opera here, QQ here, so go explorer there, that means we need a variable after the name and also a variable after Y since these values are also changing. And what we're doing is we are constructing a list comprehension. So for V one and V two in. So where do we get this? Basically, we need for V one, we need the names for each course, the titles of the courses. And for V two, we need the number of ratings for the course. So let's take a look at the data frame, how it looks like, share. So I think the index has the course name. Let me show actually that you. I'll execute that cell and execute that as well. So we get this, but share that index is basically a list like object, which contains all the names of the courses. And share actually list share contains the number of ratings. What we're going to do is we are doing for V one, V two in Zip share dot index, share print V one, V two. And what's happening here is that in the first iteration, that is going to print out V one, the title of the first course and the number of rating left for that course. So v1v2 then v1v2 again and again and again. That's what we need here. So for v1v2 in Zip share sorry, share index and share. So those values are going to be injected into here and here in this dictionary. And then we assign that to this, and then we stop the script and we run it again to see where we are. So we get an error. Attribute list object has no attribute data. So let's go take a look to where the error occurred, a line 84, which is here. And it says List object has no attribute data, which means that this is the last object, and this is the data attribute. Since that is a list, of course, it doesn't have this data attribute because we thought this was a dictionary. Somehow I thought maybe you didn't. So serious. Hmm. Series is really a list. So that was a logic mistake for my part, but that is what errors are about. So they explain to you what's going on. You read that, and you fix the issue. So since series is a list, it means it has items, and in this case, it has only one item. So it's the big dictionary which has this key and value, that key and value, and that key value. So the series list has only one item. Therefore, we need to access that one item. From series, so the item with index zero, that then will give us this dictionary. And out of that dictionary, we extract the data key of that dictionary. So by extracting data by accessing the data key, we get the list of the data key. So now we should be fine. Hey, it looks good. And that ends this video as well, and that was a series of graphs that we developed throughout these sections. I'd like to thank you for following, and I'll talk to you in the next videos. See you. 151. Demo of App 5: Web Development with Flask: Building a Personal Website: Hello, and welcome to this new section of the course. And this is the very first lecture where I'll give you a demonstration of what you're going to be building in this section. So this is one of those sections of the course where you're going to build an application. This particular application is a website with Python. Python can build websites, just like other programming languages. Of course, you need HML and you may need CSS and JavaScript as well for the client site to render the web page on the browser. But on the back end, you use Python, just like you do with PHP and other programming languages. Yeah, the website that you're going to build is this one here that you see. I mean, it's quite empty for now, it doesn't have any content, but you can fill it with content and use it as a showcase for your work, as a portfolio or anything. So once you reach this point, you can improve it with Easy. Also know that this website is now live, so I'll teach you how to deploy a website on a live server so that everyone can browse and visit your website. So it's a complete tutorial to build the website from scratch and make it work online. And now this is a static website. But later in the course, we have other applications where you'll be building more dynamic websites with database on the back end and also some dynamic features. But this is a great point to start. So I hope you enjoy this section, and if you have questions, just feel free to ask. And yeah, I'll talk to you in the next lecture. 152. Your First Flask Website with Server Warning Added: Hello. And in this lecture, you will build your first website with FLASK if you haven't done so already. FLASK is a Python framework that has all the tools and the templates and the functions for you to build websites with Python. And before going deeper into FAS and explaining you how to use FLASK probably for building Python web apps, I'd like you to spend 3 minutes to build a very basic website with FLASK. And that is done with only several lines of Python code. So that's what we'll do right now. To build a web app with FLASK, you need to have Flask installed. So PIP install Flask should install Flask in your Python environment. All right. That was successfully installed. And let's create our website now. What you need is a Python file. So I'm creating one here. Let's say, script one not pie. And then here is where you write the code that will build your web app, and everything starts from importing Flask. And actually, you don't import the flask framework, but you import the flask class from a flask framework. So from flask import flask. And FLASK is a class of this library, and this contains all the prototypes that you need to build web apps with Python. So this will handle requests for you. You don't have to set up requests yourself. But let's focus on this example for now. Once you do that, you need to create a variable where you will store your FLASK object instance, your FLASK application. That would be equal to the FLASK class. And you pass the name variable in there, don't worry about that right now. Then you need a decorator, root, and here is a URL where you'll view your website. So this slash here means the homepage. And just after that, you need to write the function, the Python function. And this function is what defines what your web page will do. In this case, we will return a string. Let's say string here. Website content goes here. Just after that, you need two more lines of code, and that's a conditional statement. If name equals string main app dot run. Debug equals True. That's it. Don't worry about this right now. Just click Save, open the terminal, and executor script with Python script one, Python. And it looks like your web app is running now, so open the browser. And your website should be live on your local host. That's it. Nothing impressive, but you see how easy it is to create a website with Python. And in this case, we are just returning a string gear to the website. So there's nothing fancy in there. But later on, I'll explain to you how you can return HTML pages instead of playing Python strings to your website. That will allow you to actually have different formats, different fonts on your text, and then you can also apply CSS styling to your HTML, and so you'll have a complete website with modern features. For now, let's make sure you understand these seven lines of code. Yeah, it's seven lines. As I said, the first line, you are importing the FAS class object from the FAS library. Then in the next line, once you have imported the flask class in here, the flask object, in other words, you are instantiating that class, that object. This here is a special variable that will get as value the name of the Python script. Now, when you execute a Python file, a Python script, Python assigns the name main this string to the file. When you import a script into another script, like if we import this script from another script, this script will be assigned the script one dot py name. But when you execute this script, Python assigns the name underscore underscore, main score underscore. So what happens is that? In this line, we say I name equals to main, then around the app. This is true when we execute the script as we did here. But if we imported this script from another script, this line here would not be executed. So this allows us to have control over this script using this line here. Then we have these two lines. This is a decorator. Now, the output that this function produces will be mapped to this URL. So if you want, you can change this URL to this, for example, save the script. Sure, you need a URL here. Save the script, run and go to the local host, reload. And this time you'll get an error. Python couldn't find this page, but it can find the about page. Yeah, that's it. If you still want homepage, you add another decorator and another function just after the decorator. So just leave with this homepage and just say homepage. Here. Save. Again, we have an error because we cannot have functions with the same name. So we can change this to a bot. The name doesn't matter. So this doesn't have to be the same with this one. Click Save on the script again. And go to the website. This is working. Try the web at the homepage. This is working, too. If you want to change something, let's say about content goes here, you save the script. And the web app will restart by itself so you don't have to close the web app and run the script again as I did earlier. If you get an error like I got previously, the script will stop. But if everything is right, you will not get an error, so try this again. Homepage is fine. About page is fine, too, and with the new content. So that's about it. In the next lecture, you will learn how to return an HTML template, an HTML file using your Python functions. That will give you full power to publish anything that you want in your website and not just play strings as we did in this lecture. So we'll see you in the next lecture. 153. Preparing HTML Templates +: Welcome again. In this lecture, you learn how to generate HTML pages using your Python Web App. In the previous lecture, we simply return some plain strings, as you see here, so return a string. Now we will return an HTML template in here. To do that, we need to use the render template method of the Flask library. And what render template does is accesses an HTML file, stored somewhere in our Python application, in our Python files, and then displays that HTML all the requests at URL. So we need to replace this with the name of an HDML page, let's say home dot HTML. And this name here, this file name has to reflect a real HTML file, which has to be stored in a folder, which itself has to be named templates. So be sure you use these names when you create a folder. Inside the folder, then you need to create an HTML file, home dot HTML. And the name has to reflect the name you are returning here in the Eder template method. That's it. And here is where you write the HML code now. If you know HTML already, this should be as easy as breathing. If you don't know, then it should be easy to learn. If you know a bit of Python now, which you should learning HTML is just a breeze. So just go ahead there and learn some HTML. It's that easy. But anyway, I'll create an HTML file here. Everything starts with a declaration of the document type, HTML. Then you have the HTML tags. There was an opening tag, and you also have a closing tag. That's it. You have body tags. Just like that, and inside here goes the content of your web page. Let's say I want a heading like this. And inside here, you can put some text. My homepage, for example. And here's another different type of tag, which is a paragraph tag, and say this is a test website. Clicksaf and, yeah, you should be good to go. Go to your script, make sure you have saved it. And the web is restarting, and I'll go now and visit my homepage. This is the bot page. This should be the homepage, how. I seem to have a little typo in here, I guess. Yeah, this should be page one as the opening tag. Click Save and you don't have to rear on the Python script. Just go here, reload the page. And this is a normal text now. So this is a paragraph, and this is heading Great. So we can also have another page for the About page. If you want just quickly duplicate this, say about my About page. Here, this is a test website. Again, just like that, you go to your script one and change this to render template, and there you pass about dot HTML. Click Save, go to the local host. This should be the homepage. You have the About page. Yeah, my About page. This is this website again. So, that's it. That's how you pass HE Mel templates to your Python web app, and that's how you map them to your URLs. Let's move on, then to the next lecture. 154. Adding a Website Navigation Menu: Okay, in this lecture, I'll continue working on the website. And specifically, I'll be adding a navigation menu so that the user can easily navigate through the pages. Let me illustrate the idea first. At first, I'd like to execute what we have so far. So Python script one. So the application is running. And if you go to your browser, local host, the default port is 5,000, and this is the website. And we also have two pages here. About page. Good. So about page and homepage. Now, what I'll be building in this lecture is this thing here. I have a screenshot. So the homepage, the About page, homepage, the About page. So what we have is a navigation menu here, which if you click one of these texts here, you go to the specific page. And we also have a heading and something you should notice now, which is important to notice is that this part here is the same in both pages. That means we will add this part here, the code of this part in HML page. How does that sound? Well, it doesn't sound very smart to me. A smarter way to do this would be to actually create a separate HML page for this part here, and then link the A page and the homepage to this page. So that's what we'll be doing in this lecture. So we need to have the HTML code for this header and the navigation menu. And I already have that code, so I'll not go and type down all the HTML code. Here. All right. But I'll explain to you what the HTML does. So first of all, I'd like to actually double click this and just show it locally. So we're not running this on a server, double clicked it. So we have the header here and the navigation menu, which if you click, you don't go anywhere because we haven't yet linked the layout that HTML page with A and the home page. And as you can see, I put this inside the templates folder. So every HML page goes to the template folder. So what we have here is we have the document declaration and we have the HTML tags the closing here. Then we have a header element, and this contains DF here. And we'll be using this class name later to refer from our CSS code. Then we have a function here which says URL four. And what this does is that this will trigger the home function, the Python function. Which we have here. So this one here, this function will be triggered when the home link will be clicked by the user. So this one here. And so the same for the ab. So when the user clicks about, the Python function will be executed and the about that HTML file will be rendered through the render template method. So I hope that is clear. If you're lazy like me, you don't want to type every line of this file, you can find this file in the resource section, which is on the right of the screen. Now we need to figure out a way to link this layout HTML file with the home and the above HTML pages. I'll quickly go back to how the page looks like. And so as you see here, we have the header, and just down the header, we have the A HTML page. So just here. That means just under the header, we will enter some code that will link to the home dot HTML page or the A dot HTML page depending on what the user will click. And so we have a division here, closing it. And I'll give it a class name so that I can refer later to the CSS code. Then you have curly brackets. So that's a syntax, and you also have to use percentage sign there. Then you write the block tag, and then you give a name to the block. And what we're doing here is actually template inheritance. So the layout dot HML page, which we are modifying right now, is a base template. The child template will be the home dot HML page or the about dot HTML page. And this child template will fill in this block here. There is another line inside curling brackets and percentage signs as well. That is the end block keyword, which indicates the end of the block. And we are done with the layout HML page. What I'll do here is go to Panes and split the window right. So I have the layout dot HTML page here, close it here. And I'll go to the home dot HML now. And because this will be a child template, I don't need the declaration here and the HTML tag, and I don't even need the body tag. I'll replace this with a DIV. And let's say class equals Home close it here and delete this two. And what you have to do now is use the templating syntax again, like that and use the keyword extends. And then you declare what you want to extend. Lay out that HML file. Then you also need another line. And here you need to specify the name of the block. So this needs to correspond with this one here. And so what's going on here? Well, let's go to the script to the Python script. What happens is that when the user visits this URL, so the homepage or this one, let's say this one, Python will execute the home function because the home function is mapped to this URL, and the home function will render the home dot HTML template. So Python will go to the home dot HTML page, and it will see that the home dot HTML page extends the layout dot HTML. So this one here. So what it will do is that it will send this code in this block in here, and then this page will be rendered in the home URL. So as simple as that, the user will see the layout that HML page with its child content. So this is base template, this is the child template. And we also have another child in this case, which is about that HML. So let me bring this here. And I'll just copy this I put this here, and this as well. Control C, and yo. Make sure you have saved all the files and this one. Yep. And let's take a look if the app is running. Yeah, it looks live. And I'll go to the homepage. Yeah, it looks good. We have home and at. Let's go to about ink. Yep. We have seem to have lost the heading here. The format of this line, let's have a look at the ab page. Yeah, I forgot to close the Div here, save again, go to the browser, reload, and it's fine. So that's about it. I hope things are working on your side. If not, please feel free to ask a question, or you can even check my files, which I'm putting in the resource section on the right of your screen. And yeah, I think our application is ready for more. So let's move on and see you in the next lecture. 155. Improving the Website Frontend with CSS ++: Great. We have progressed quite a bit. We have a Python script that generates Flashcap and we have two functions. And each of them maps two HML pages to two different URLs. And this is our website with two web pages. In this lecture, we will add some CSS styling to this website so that this looks just like any other modern website, and it is visually appealing, and it doesn't look like in the 80s. Alright. To do that, we have to do basically two things. The first thing is we need to create a CSS file and write the CSS code inside it. And the second thing is, once we write this CSS code, once we have the CSS file, we need to link to it from our layout dot HTML file. CSS is a CCS HTML. So if you don't know it I suggest you look at some tutorials, and I'm sure you'll get used to CSS very quickly. I already have a CSS file that will stylize my website. I'll cut this and put it in a folder which I'll call static. Inside here, I'll create another folder and call it CSS, and I'll paste the CSS file just inside here. So let me close this. As you see, the folder I created and the file has been reflected in the tre view here inside atom. So the idea is that Python looks for static files in the static folder. So here inside static folder, you can put different files. For example, if you want to add an image to your website, you'd create a folder here called Images, and then put images inside that folder. Then you can link those static files from your layout HTML page or from any other pages. Now, before opening the CSS file and going quickly through it, I'd like to show you how you can link to the CSS file. Now, remember the visible part of an HTML code goes inside the body text, while links like links to JavaScript files or links to CSS files, go outside of it. And those should be put inside head tags. So head here and head there. And then we have a link tag. And the L there means the relationship. So the relationship to the file we are linking to is a stylesheet. So we're sort of declaring the type of the file we are linking to. So it's a CSS stylesheet, and then we have the reference here which will be equal to the URL four function, which takes as argument, the folder name where the file is located and file name parameter, which is equal to CSS main dot CSS. So what we got here is we declare the type of a file we're link to, and then we put the link of the file. And this should be in quotes. So all of this. And I'd also like to add a title for the website, let's say, Flask app. That's it. I'll save this. And I'll go and try out the website. Whoa. Can you see the difference? Yeah. We have the menu here very nicely. About page, homepage, and we have the title just here. And then the content of the webpage goes here. Now, all these bars here, the background color, the paddings, all these have been defined using CSS. So let's go ahead and have a look at the CSS code. It is. I believe this is quite self explanatory. But anyway, what we have is basically, this is an HTML element, so the body is here. And once we write the HTML element in the CSS script, we use curly brackets, and then inside the curly brackets, we define these attributes. So the margin, the painting, and the font family for the text and the color of the text. If you want to change this, let's say 999, save and go to the webpage reload, you'll see that the text got some different color. So this is quite grade. So that means this attribute here is affecting the body of the website. I'll put this back to four for four. Then you have the header element, which is responsible for this header here. So at the top. Then if you want to stylize a specific part of your web page, let's say, only the logo, which is this one here, you'd have to refer to the header first and then to the agon element, and then you refer to the logo class. So this is a class name just here. And so on and so forth, you can look at this code at your own pace, I believe. So the logic is the same. Great. And now we are ready to deploy this website online on the Cloud. So we will do that in the next lectures. See you. 156. Creating a Python Virtual Environment: So we have a running website, which looks quite good. The problem is that this is in our local host. So the only person seeing this is, yeah, you or someone who has access to your computer. So what we want to do instead is to deploy this website on web server or on Cloud, as we will do in this course. And we'll be using the Hogu Cloud. Heroku is a service that allows you to deploy Python applications in their cloud. Good news is that you can deploy an application for free, and you can have your public domain for free as well. Though you'll need a subdomain of Heroko so something like let's say ardit.heroko.com. However, if your site will have a lot of traffic later on, you'd want to actually upgrade your plan and buy more bandwidth. Deploying on Heroko is relatively easy. You don't have to think and to do any administrative work, so a Heroko saves a lot of time and effort so that you can focus on programming instead of the server parts. Before deploying to Heroku, though, we need to do something. There is something that we should have done since in the beginning of this section. So even before writing any file here, and what you should do is that you should create a virtual environment which is isolated from your other files and from your main Python installation. So to run our application, we use Python, which is coming from our main installation. So this one here, the ones I have here. This is not a good practice. A good practice is to actually have a clean installation of Python, which is used only for your application. So in that installation, you don't want to have libraries install libraries that you don't need for building FLASK applications. Therefore, we need to create a virtual environment. And here, I'll show you how you can do that. To create a virtual environment, you need to use a Virtual F Python library. And to use the Virtual Python library, you need to install Virtual F. So PIP install Virtual NV so we are using the main Python installation here to install Virtual ENV. Great. That was successfully installed, and now we will create a virtual environment. The virtual environment should be created at the same level with the main folder that holds the application files. So if we go to our directory, just here, here is where the files are. And what I'll do is create a main folder in here and call it my site. And I'll close atom for a while. And this would go inside this. So just here. And now you can open atom in this directory because here is where we will create the virtual environment. So let's open the command line now, and we are ready to create a virtual environment. And to do that, you should use a Visual M library by saying Python. The argument, then you have Vn, which is the name of the library of the module. And here is an argument which allows Python to locate modules for execution as scripts. Then you need to specify a name for the folder where the virtual environment files will be stored in, so that should work. Let's see the virtual folder was created. And, the environment was created successfully. What we have here is an isolated installation of Python, and inside scripts, you'll see that you have Python there. Here it is. Okay, don't worry about that. And here is PIP, as well. So pip dot. And that means you can use that Python if you like. Let me try out. So we are now at the Mside directory. That means we need to refer to virtual crypts and Python. And that will trigger our fresh Python in the console. However, we are not interested to actually run Python from the shelf. So I'll just exit this. And what we're interested instead is to actually run the FLASK application using the fresh installation of Python. But before we do that, we need to actually install Flask in our Visual Python, if you like. And to do that, you need to use the PIP library of your isolated Python. So you need to point to the virtual folder to the script folder then and then to PIP install Flask. And so FASC is installing and it also installed its dependencies. And we should be good to go now. So let's run our webapp using our new installation of Python. To do that, you need to point to the new Python and that to demo, because we are in my site now, as you see here, so Demo backslash script one dot pi. That should work. Great. And if you go to the website now, you'll see that it's working fine. That's it. Now you are more than ready to deploy your FASC application on the cloud, and we'll do just that in the next lecture. And I'd like to mention it again that please keep in mind that you should always create a virtual environment before you create your FLASK application. So before writing any code, you should use fresh installation of Python. 157. How to Use the PythonAnywhere Service: Hi, welcome to a new lecture on how to deploy your Flask web app on a live server, which means that you're going to have your own domain name which you can give to anyone and they can use your web app. And we're going to use Python Anywhere. So go to python ware.com. Python Anywhere has a free service where you can host your FLASK applications. So this is what we're going to do, and it's relatively easy to deploy on Python anywhere. So this is an updated video actually, of course. Before this, we used Heroku. Now, Heroku and Python Nware both allow you to host to deploy FLASK applications for free. The difference is that Python Aware tends to be more user friendly. And Heroku, on the other hand, makes it harder. So I usually suggest that as a programmer, you want to focus on your codes instead of dealing with server administration issues. Although I'd also like to say that both Hiroko and Python ware are relatively easy compared to if you had your own server where you'd have to handle everything. So still, Hoco and Python Aware makes things easier. To be able to deploy your FAS web app on Python anywhere you need to sign up for an account. So go to Pricing and sign up, and you want to find the section where you can create a beginner account because that is free. And they also have other plans paid. So if you have more visitors, then you'd have to upgrade to a paid account. So I'm going to create a new account. All right, so I signed up and my username is Ardit 12345. That's my username, and this is a dashboard. Now, on Python anywhere, besides deploying web apps, you can also do some other things. So before we deploy the web app, let me give you a short tour on Python Anywhere. Basically, you should be able to see the dashboard menu here, and then we have consoles. In consoles, if you go to consoles, basically, you can create a Bash console. And that gives you access to your own server where you'll deploy your web app, and you could also do other things such as you can start Python three. And it starts that version of Python. So it's an interactive Python you can even import some libraries here, so Pandas is already installed, you can use it. The downside of this is that you don't have a graphical user interface. So if you want to show to generate some graphs and you want to see them, that's not possible on Python anywhere because all you have is this shell. So the Python shell, and you go back to the terminal. And for example, with PWD, you can see where you are currently. So that's your location in the server. So you are inside home, then inside the 20 2345, so that folder of the home folder. Here you can also create Python files, for example, Nano example dot PY. Nano is a text editor, which you can use in this kind of command line interfaces. So that will create a new file, and here you can write Python code such as print. Hello. Parenthesis. Now, to save this file, what you want to do is you want to follow these commands. So exit. You want to exit with Control X. So press Control X. You'll see this message. It says, save modified buffer, which means do you want to save this file? Y for yes or N for no. So I'm going to press Y, and then it asks you again what name do you want to put to your file? Example dot PY S it is, yes. So just press Enter. Enter and the file is saved. To run it. You do Python 3.9. Example dot PY, run and you get the output. So that's what you can do with the console. If you go back, then you have these files. And here now you can see that example PY, which we created previously is here. And you see the current directory, so a home Rit one, two, three, four, five, that's a directory. We were in the command line interface. So this is another way to create files. So if you want to create a file here, you give a name in here. Let's say example two PY and go to New file. And let's say here I am print. Hello again. And now you can also run this file, save it and run it from here. So save it first and go to the Run button. And you should see the output down here. This is a bit slower than the previous way to run application to run Python files. But anyway, this is the output. So that's another way to run Python files. You want to go back now, you can press in here. So this is a Files page, and then we have web. Here is where we will create a new web app, but in the next lecture. Then we have tasks with tasks. What you could do is you could enter here the path of one of your Python anywhere Python files. For example, if I wanted to give the path of example PY, I'll say home.r1, two, three, four, five, the directory and example PY. And then define a time. I'll set a time here in UTC time system. This script then would be executed at that time every day. This could be useful for things like web scraping if you want to script something at a certain time every day, you can do that on Python anywhere as well. Lastly, we have a databases. Menu here is where you can create a database. So if your web app has a database where it saves the data, you want to create a new database here and then create a table for that database. Again, you can do that in this interface here in databases, and then your web app will be able to interact with this database. So this was an introduction to Python Anywhere. In the next video, we're going to deploy our Python app, so our flashap on Python anywhere. See you. 158. Deploying the Flask App on PythonAnywhere +: Welcome back. I'm excited to show you now how to deploy your web app on Python Anywhere. So this is my Python Anywhere account, and I am in the dashboard section currently. You want to go to web and there you want to create a new web app and you get this message here. Python anywhere is letting you know that you cannot have a custom domain name, let's say, ardit.com because this is a free account. If you want a custom domain name, then you want to pay to get one of the paid accounts. First though, you want to find a domain provider to buy a domain name. So if you want to buy the domain name example.com, for example, you would want to go to maybe name chip. Name chip is, I think the best one to get domain names. So name chip.com, and once you buy a domain name there, then name chip will give you some DNS names, and those names you have to put here in a Python anywhere to connect them to your web however, we're not doing that now. For our purpose, it is enough to have this kind of domain name, which is, in my case, this one in here. So Rs one, two, three, four, five, dot Python Anywhere, dot com. So this is a subdomain of Python aware.com. Press on next. And you have several options. The one we want is FLASK, so you can deploy different types of web apps on Python anywhere. We press on FLASK, and Python 3.9 is good to go. So press on there. And this is now the entry point of the Flask app. By entry point, I mean, the file that you run to start the FLASK app. So in our case, it is script one dot PY. That's a file that we run with Python script PY. So don't change that, leave it as it is. So press next for now. And the app is created, but we need to add our files to our app. So for that, you want to go to the files menu. And now here on the left, you can see my site. If you click there, you're going to see the file that Python Anywhere created. So this is the entry point that I was talking about, Flask Underscore app that's PY. You want to click there and you want to delete that code and paste copy your own code and paste your code in there and press on save. So you can see now that we are in this directory. So slash O R the one, two, three, 45. So your username MySite, fA FAS Underscore app that PY is our file. So if you click on my site, you go back to the root directory of your project. So that's the root directory of Python Anywhere, and this is the root directory of our local project. So script one that PY is there, and then it has a static and a template folder in the same root directory. Therefore, in this Mist root directory, we want to create a template folder. So write templates there and press on new directory. That will create a new template folder. You see now it changed to this folder. So if you go back to my side, you see templates is added in the directory's Flask underscore app is also in the same folder, my site. And we also want to create a static folder empty. New directory, press on that button and it should create a static folder. So go back to my side. You see static and templates are there now. So we need to add our static files. So press on static. You are on static inside static now and you want to upload main that's CSS, but wait, this is in another folder. CSS is the folder, so you want to create inside static. You want to create a CSS directory. Press on new directory. Make sure you are in that directory, so my site slash Static slash CSS. And here now we want to upload the file. And that file is this main Css. So here I am This is the project directory with our local files. Under Static under CSS, we have main Dot Css. Double click, and it will upload inside CSS. Then go back to my site, go to templates and upload. The files that are inside templates, which is about home dot HTML, and the third one, layout dot HTML. These three are inside templates. So make sure they are inside templates. Then go back to my site and just have a look if everything looks good. It looks good to me. One change you want to make also is that you want to go to your app, and when your app is in production, you want to change this to false. So you don't want to show visitors Python errors because that could make your app prone to hacking. Because people or hackers will see the errors of your app. They may understand how your web app is structured and you may also expose data which you don't want to expose in those debug error messages that Flask shows. So false and present safe and now we are ready to see our app, but after we have reloaded the app with this button. So under the web section, press and reload that button to get the latest version of the files served by Python anywhere. And then you want to click on that URL. So that's the URL of my app, press there, and my site is online. So it's working just great. I hope yours is working, too. If not, then you want to go back to the web section and scroll down and locate these error logs. If you press there, you're going to see the latest errors that you got from your web app. So these are Python errors and try to read them to understand what's going on. If you don't understand them, feel free to post a question in the Q&A, but make sure to copy paste these errors there and also the code of your web app, and we'll be happy to help you. Thanks a lot. I'll talk to you in the next videos. 159. Introduction to the Tkinter Library: Hello, and welcome to this new section of the course. In this section, you're going to learn how to build graphical user interfaces with Python. And specifically, we're going to use the Tkinter library for that. So in this section, you're not going to build any real world program. I'll introduce you to the Tkinter library and, of course, build a graphical user interface, a small program that can get you started with Tkinter. Then in the next section, so once we're done with this section in the next section, you're going to learn how to interact with databases with Python. So we'll be using Python as a wrapper of SQL code so that we can store data in a database query data, delete and so on and so forth. So that was a section after this one. And then in the first section after these two sections, we're going to build a real world program. And that program is this one here. So I called it bookstore, and what this does is it allows you to store book information in a database. This is a graphical user interface. So this program is made in two parts. You have a graphical user interface, which are the button seer, which are called Widgets. And this was built with Tkinter. And then you have the back end, which consists of code that communicates with the database. So for example, if we press the view button, we are acquiring the database to load all the books for us. Oh, we have the title. So if you press one of them, you get the title here, the author and the year of the book. And also the book identification number, which is called ISBN. You can also search for an entry. So if you want to search for an author, you write the author name, Ni and press Search. And if you want to add an entry, you just type that in. And yeah, something like that. Add entry. And if you load them again, your entry should be here. So this is a program. We're going to build two section after this one. So let me close this one here, and in the next lecture, I'll introduce you to the Tinder library. So we'll be building some simple interfaces with some widgets. I'll see you in the next lecture. 160. Creating a GUI Window and Adding Widgets: So here we go. I have opened up Atom here, so I'm going to use Atom to build the bookstore program, so to say, that uses kinder and Aquia Light three as libraries. So I'll go ahead and create a new Python file in here. What script. Won pie. Now to build graphical user interfaces with Kiner, you need the inter library, and you don't have to install it because Tkinter is a built in Python library. So all you have to do is go ahead and import Tkinter. If you are on Python two, this would be with at T. In Python three, it's Tkinter simply like that. Good practice, however, is to actually import everything from Tkinter. So from Skiner import all So why we do that? We do that because we're going to use a lot of Tkinter objects in our scripts. So it makes sense to just load them all instead of referencing them with Tkinter dot button, for example. Instead of doing that, we can just say button, and then we enter the parameters and so on. So let me create a graphical user interface. Now, at kinter program is made up of two main things. You have the window and you have the widgets. So for example, the window is all this program here that you see, and then you have buttons and things like that, which are called widgets. So first of all, you need to create the window. And I like to call my variable window, and that would be equal to decay. That's it. That would create an empty window for us, but we need to do something more here. We say window that main loop. This is always necessary. So we open a window, we create a window, and then everything goes between these two lines. So you create widges between these two. And this is necessary because if you don't have this, your program will open up and it will close in a split of a second. So basically, this allows you to actually press that button on the corner of your window and close the program. So this should be always at the end of your code. I'll save this script and going to execute it. And we got an error, it says TK is not defined, so Python is not recognizing this function here because it should be T. And execute again. And this is the window, and it has nothing inside, so let's go ahead and add a button. So we store the main window in a variable, and we're going to do the same four widgets. So we're going to create variables. Let's say B one equals to button. So the button is a function that generates a button widget. The bottom function takes some arguments. If you want to get a full list of arguments, you'd want to do some code introspection. Let's say iPython here. And from skin to import. Pull, and then let's say button and a question mark. And here you can see what parameters you can pass to the bottom function. Now, the very first parameter you'd want to add to widget is the variable of the window of the main window. So you need to tell your widget, the window that the widget has to be packed too. So window and then you can pass parameters like the one you see here. Let's say, one of the main parameters would be text. So text equals, let's say, to the string execute. So that is the text the label that will be displayed over the bottom. Now, if we try to execute this script now, you'll see that we don't have a button yet, and that's because we haven't specified where to put that bottom. To do that, you need to use the pack method, which is a widget method and then execute again. And now you see the bottom. However, there is another way to actually put your widget in your window. That is a grid method. Grid. And often it's a matter of preference whether to use pack or grid. But the idea of grid is that with the grid method, you have more control on the position of your buttons or your widgets in general because here you specify the row and the column where you want to put your bottom. So everything starts from zero. And so the first row has an index of zero, and the first column has an index of zero and so on. I actually found illustration for that. So this is kinder program, and we have two rows here. So we have this first row, which should have an index of zero, and you have the second row, which should have an index of one. And you have columns, so zero, one, two, three, and so on. And let's say the OK button, which is this one here would have a row of zero, one, two, so two for the row, and then zero, one, two, three, three for the column. Then you might also have widgets which span in more than one row or column. In that case, you'd add another parameter here called rowspan. And that would be equal to a number. Let's say if you put the button would span in two rows. In our case, this is not necessary, actually, because we don't have lots of widgets. We only have one button. And so let me execute this script now and see what we get. So we get a button, which actually does nothing because we haven't specified what action to perform when you're pressing the button. And I'll explain that in the next lecture. But for now, let's add some more widgets here, just for you to get more familiar with widgets. So let's add an entry widget. And let's say E E one for that. So entry one equals to entry, and then guess what is the first parameter. And that's the window parameter. And we can leave it like that for now. And let's say a E one grade. And let's keep it in the same row and in column one. Save execute. And here we have an entry. So what's an entry. An entry is like an area where you can enter a value, then you can interact with that value in your script. So let's say you enter kilometers here and you'd want to have a button that converts those kilometers to miles. So the button would get the value of this area here, and it would display it in another widget, which could be a text widget. So let's add a text widget. Let's say T one equals text window, of course. And let's say T one, grid row zero column two. That's it. Execute. We got a very big text widget because the default size, the default height and width is actually quite a big number. So we need to specify two parameters for the text widget. We would need to put the height. Let's say one cell and the width. Let's say 20. And so this is the widget area. And this is the entry, and this is the bottom. And that's it for this lecture. In the next lecture, I'll show you how to put these widgets in life so that they can actually do something. See you in the next lecture. 161. Connecting GUI Widgets with Functions ++: Hi, again, in the previous lecture, we build this graphic user interface with Kiner. And the problem is this does nothing for now, so we press this, but it doesn't do anything. So what I'd like to do here, the final output that I'd like to have is when I execute this bottom, so we have an entry here. We can input value, and I want to execute this button and get miles here in the text area. So miles is like 1 kilometer unit is equals to 1 mile times 1.6. So if I execute this, I want something like 16 here to be generated. So a very simple program. Note that this is not one of the real programs that I promised to build in this course. So this is just to get you up and running with kinder. So let's close this now. And to have a button do something, we need to add a command parameter here. So the command parameter takes a function here as argument, as a value. And then when you press that button, execute button, in this case, the function that you have here will be executed. So let's say we have a function here that kilometres to miles. Let's say this function for now, it just prints out some text. Let's say success, for instance, because you know, it's good before you write your actual program, it's good to use print statements to try things out. So that allows you to isolate your problems. If something happens here, you know that you can't have a problem with a print statement, but if you had more complicated expression here, it gets harder to know whether the problem happens in here that you are not pointing to the correct function, or you have a problem with your statement. So it's good to use simple statements first, like the print statement. So you'd go here and kilometers 2 miles, that is the function. And one thing you should keep in mind is that you don't pass the brackets here. So this is not usual function call. You are just referencing to the function here and let Python take care of the rest. So the function name goes here and let's try this out. Execute, and you see that we got success printed out in here. Press again, success success, success. So it's working. However, we don't need to print out success in the command line. We want to print out a value in the text area. Now, we need to look at the entry widget. B here is where we are going to get the value from, so the user enters a value in the entry widget, and then we grab that value and then we use that value in our function. And for this, there is a parameter called text variable. And that would be equal to a string var object, which we have to declare further up here. So let's say you want value, so that's variable, and that would be equal to the string var function. And then we point to E one value variable, which we have just created. So this variable will get the value depending on what the user will input in the entry widget. Then we can use this value whatever we like. Let's say we want to print that out in value, and we also need to add something extra here, which is a get method of the string object. So this is a special object. It's not a string, a Python play string. To get an actual string from out of this object, we need to apply the G method. So save this and try the script. Let's say, ten here, execute, and we get ten printed out on the terminal. So we haven't yet connected this string here with a text widget. So let's do just that here. The idea here is that we need to insert a value to the text widget. And to do that, the text widget has a method called insert. So you need to refer to the text widget that you want. So T one is our text object, and then apply the insert method. And the method gets an argument first, which is a place where you want to insert the text. Let's say we want to insert at the end of the text widget. For example, let's suppose you are inserting many lines of text in your widget and you'd have to apply to execute this method multiple times. And each time if you put you enter the new text at the bottom of the existing text. So you're saying put at the end this text. You want value dot G. So the string of value that the user will enter in the entry widget. So let's see how this goes. Execute the function and put some text here. You can also put anything there, execute and you get the string printed out in the text widget. All right, but we don't want to just grab this value and insert it in the text. We want to first do something with this value, and then we insert the product, the output in the text widget. Let's say we will grab the on value dot get, and we will multiply that by 1.6. And that would be miles. So miles equals to the value that the user inputs times 1.6. So you are asking the user to input kilometers, and 1 mile is equal to 1 kilometer times 1.6 actually is something like 1.6 or six. I don't remember the exact value, but you get the idea. And lastly, you'd want to pass miles in here. So you want to insert the output value in the widget, safe. And execute. And I expect to get an error here. Let's say ten. Yes, we got an error. And so when you get errors, don't just try to copy this error and paste it on Google and try to see what other people are saying. You may waste a lot of time. Instead, invest some time and try to understand this error. So what this is saying, it says type error. Can't multiply sequence by non integer of type float. So a sequence can be a list can be a string, a tuple, et cetera. Python is trying to multiple sequence with a non integer which is a float. So float here is the 1.6 number, and Python is trying to multiply 1.6 with a sequence with this here. So this is not a number because the G method actually grabs a string out of a string object. And a string cannot be multiplied with a flow number. If this was two, it was possible to multiply. For example, if you multiply M, the string M times two, you'd get Mimi. So, but you cannot multiply me by 1.6 because it doesn't make any sense. Anyway, so the solution to this is you want to convert the value that the user inputs to a float, and you do that by adding the float function. So watch out for the brackets. You see there is an underline under the bracket and you have an underline here. So this means this bracket closes in here. So everything looks fine, safe and execute again, ten, and execute. And we get the expected output. You can delete the print function. We don't need it anymore. I believe that was a good start with the Kiner library, and you should now be able to make more advanced interfaces. However, we will be building a real advanced graphical user interface with Kiner, which will interact with the database, so it will be a real world program. And for now, I'll just hand you an exercise in the next lecture so that you practice Kiner a little bit. And you also get to know with some more cosmetic aspects. So you'll make the program that we built in this lecture, you'll make it more visually appealing and and you'll make sure you'll get your hands dirty with kinder a little bit. I'll talk to you later. 162. How Python Interacts with Databases: Hi there, and I'm glad to introduce you to this new section of the course. In this section, you're going to learn how to interact with databases via Python. And what that means is that you'll use specific Python libraries, and you're going to operate a database from Python using Python. You're going to do operations such as inserting data into database tables. You'll be able to update data, delete, and query data from the database. Then you are able to use those data in your Python program. Python is able to interact with many databases such as MySQL, Post gracuLOcle or SQLite, et cetera. In this section, you're going to learn how to interact with an SQL light database and post SQL database as well. SQL Lite and PostgrasUL are different in that. SQLite is not a client server database. Instead, it is embedded into the end program. So what does that mean? Well, let's look at this program. If you follow the previous section, you know that we're going to build this program in the next section. When you click a button here, you see some data, and these data are stored in SQL Lite database. In contrast to other databases such as postgrad SQL, SQLite is based on file. So all these data here are stored in dot DBFle database file. So that means you can just give this program to someone else who don't have SQLite installed, and they can use this program, so they can add more data here, can update data and delete them and so on. But if you have this program in postgrad SQL database, the user you give the program to, they would need to have PostgreSQL installed in their computer to be able to operate the data. So consider SQLite, small database, and you can call it portable, but it's very popular and post grascuL would be more appropriate to use in a web application. So let's say you have some forms, you're getting some data from the user on your website and you store your data on a post grascuL database on your server. Python is a program that gets the data from your forms on the client on the browser and sends those data in your database. To be able to interact with these databases, you need to have two libraries, and these libraries serve as interfaces to actually send SQL code to the database, and the library to interact with an SQLite database is called SQLite three, and the library to work with a post grad SQL database is psycho PG two. So in this section now in the next lecture, I'll show you how to work with SQLite three and then we'll jump to psychopg two. So let's move on. 163. Connecting to an SQLite Database with Python: All right. In this lecture, you're going to learn how to use SQLite three. So Acul three is Python library to interact with SQL Lite databases. So think of it as a Python wrapper of SQL code. So you can actually write SQL code inside Python using Ascoli three. You don't need to install Scull three because SQLite three is a built in Python library. So all you have to do is import cult three. Let me test it. Script one. Yeah, it's working. Now, standard process of interacting with a database would consist of five steps. First is you connect to the database. Second is you create a cursor object, and the cursor object is like a pointer to actually access rows from a table of a database. Then the first step is you apply an SQL query, so you may want to insert data in the database or select data from the table and so on and so forth. And then the fourth step is you commit your changes to the database, and then you close the connection. So let's go ahead and write an example with all these five steps that I just mentioned. So the first thing, you need to create a connection, and you want to store that connection object in a variable. So let's say C. That would be equal to cult three dot connect. And what you pass here is the database file. So let's say it dot DB. And if you don't have a database file yet, your database will be created by this line of code, and the connection will be established. If you have a database, a connection will be established with your existing database as simple as that. Then you have to create a cursor object, so cur the variable, and you need to refer to your connection and then to the cursor method, which is a method of the connection object. So far so good, then here comes the actual SQL code. You want to point to your cursor object, and then use execute method. And then inside brackets is where you enter your SQL code. Remember, your SQL code always goes inside code. So you pass SQL code as a string to the execute method of the cursor object of the SQL Lite three library. So if you're familiar with SQL, this should be easy for you. If you're not familiar with SQL, SQL is quite simple, so you'll be able to learn it quite quickly. At this point, we have a database, but we don't have any tables in the database because a database is made of tables and tables have rows and columns. So first, you want to create a table. And a good practice is to use capital letters for the SQL keywords. So create is an ascL keyword. Table is an ascuL keyword as well. And then you want to specify the name that you want to give to the table. Let's say store. That's how you order Python VasquL to create a table, but then you need to specify what columns you want, what fields you want in your table. So let's suppose we are creating a table. We have a store, we have a shop, and we want to store our products in SQL database table. So we would want to have the item. So that would be the item name. And the item would be text datatype. So text is like strings in Python, and then you'd want to have quantity. And that would be an integer. So how many of this item you have in your store and the price as well. And let's say real for the price, which should be a float in Python. So a decimal point number. That's it. Here closes the code of the SL code, and here is the last bracket of the execute method. Then you need to commit these changes to the database. So you refer to the connection and then commit, and then you want to close the connection. So that's it. You save that and go and execute. Qlite is not defined, of course, because I have made an error here at Typo. And again, and as you see, a database was created. Now, if you're on the program again, you get an error because the table already exists in the database. So what you could do here is a simple trick. You need to add some code in your SQL line. You say, create table if not exists. So safe. And if you on your code again now, nothing will happen because what Python does is, it goes and connects to the database, then it creates a cursor. And then if there is a table called store, it doesn't do anything, and it goes to the next line. If there was no table, it would create a table. So it's good to have this simple conditional here inside the SQL code. How about adding some data to our empty table? Let's try that. C execute. So we are executing some SQL code again, and the keyword that inserts data to the database is insert. Then you want to specify where you want to insert the data. So insert into store. And what values you want to insert to your store table. So values, then you open brackets and inside the brackets, you enter the values in the correct order. So in the order that you have defined your columns, so you'd have item quantity and price, and let's say wine glass. Now, this is a string, so it should go inside quotes. And you should use single quotes here because you are using double quotes for the outer expression. So if you use double quotes here, you will confuse Python and you'll get on so use single quotes. That's why we have different kinds of quotes to wrap around strings. So we have the string wineglass, and let's say we have a quantity of eight and the price of 10.5. Save that and go ahead and execute. We didn't get an error, so that was successful. Now, what if we want to insert another row? Well, we could add that line in here under this. But then when we execute the code, we would get this line executed as well. So we'd have a duplicate of this row. Therefore, what we could do in this case is we would use a function to wrap around our separate SQL statements. So you can indent this block of code if you like, you can go to edit lines indent, or you could use shortcut, which can be specific in your keyboard. So just look here for your keyboard shortcut, and then you can just use that. So the reason I'm intenting the block of code is that I want to create a function here. Let's say function create table. Don't forget the column there. And then I want a separate function. For inserted data. So that would be the SQL statement for the insert function, but you can see the difference between this function and this function. Here we are not creating a connection to the database, which is wrong. So you'd want to insert these lines in here. So that you establish a connection with the database. And then you correctly close that connection. So you know how to use Python functions now. And naturally, the need comes to pass parameters to your function here. So you want to say item, so just some variables and quantity. Price. And then you would want to somehow replace these parameters in here so that every time you call the function, you insert some arguments and those values are inserted to your table. Now, you can use string placeholders, Python string placeholders to replace these values with the values that the user will pass when they call the function. But this is not a good practice because your code would be prone to SQL injections from hookers, and that applies when, of course, when your web application is on the web. But anyway, a good practice is to put question marks in here. And then after the SQL statement, after the double code, you'd want to pass the variables that these question marks could be replaced with. So you'd want item, so in the correct order quantity and price. So let's try this all now. I'd like to execute the insert function that I just created with some new items. So let's say water, glass, we have ten of them, and this would be less expensive. Save that and go and execute. I made a terrible error here. I wrapped with code all the arguments. So water glass should be in close, and these are numbers. So save again and try it again. And your data should be know in the database. So one more time, and let's say Coffee cup. Safe execute again. Now I'm sure you would want to see the data that you have been inserting your database in your table. So let's create a function that does just that. Let's say depth view. And you'd want to establish a connection with the database. So let's copy that. Paste it here, and then here goes the SQL code, so cur execute. So we always use the execute method to send SQL code to the database. And then we have quotes. Let's say we want to select the data of all the columns of the store table. So select an asterisk, which means all from store. All right. So we selected them, but how do we actually fetch this data so that we can use them in Python? Well, the way to fetch them is by using the fetch all methods. And we want to select to store those rows in variable. So let's say rows fetch all. And then we need to close the connection. So in contrast to the other methods where we were writing data to the table, here we are just selecting data, so we don't have to use the commit method. And we want to return the rose variable. And I just like to print out the output of the function. So the output of the function is rose variable. So I'll get the rose value printed out on the command line. Save the script, execute. Of course, I have a typo here and should be returned. Try again. And here are our data. So we have one glass water glass, and we have two lines of coffee cups. That's because we executed the function earlier, the insert function, and then now that I executed the script again with a purpose to get the view function executed, the insert function was executed as well for the second time. So coffee cup was inserted two times in the table. All right, that's for this lecture. And in the next lecture, I'll show you some more operations you can do with the database. So I'll talk to you later. 164. SQLite: Selecting, Inserting, Deleting, and Updating SQL Records: So in the previous lecture, I introduced you to the SQLite three library, and I showed you how to create a table in your SQL database and how to insert data in your database and how to select data and view them in Python. So we have these four lines, four rows in our database table. And in this lecture, I'll quickly show you how to delete and update data from your table. So again, I'll create a function so let me copy this. We still need to connect to the database and create a cursor object. Then we need to use execute method. And in this case, I would like to delete the row that has the wine glass. So inside execute, we would write, delete from store where item equals, I would like to use question mark placeholder here. So mark and in brackets, we would want the parameter that we would pass through our function. So this item here is the one we put inside here, item, and let me change the name of our function. So this is this one. Don't confuse it with this. This is the column of our table, and this was the row from the previous function. Delete this as well. And you also want to commit the changes to your database. So commit. So that's it. And I'd like to comment this out so I don't want to execute the insert function again. And I want the view function to be executed after we delete the row. So delete. So item which item would you want to delete? So the item wine glass. And let's see what will happen. We got an error and ask you three error, incorrect number of binding supplied. Line 28, I can see yeah, there is something I often forget. You need to add a coma here. You'll see that when I teach you how to connect to a postgrascule database and how to query data from the postgrascule database. The code is quite similar, but it has some critical changes like this one here. So it can be confusing when you work with different kind of databases. Let's try this out again. And, it seems to be working now. Wineglass is not here. So that's how you delete a row. Let's now add another function. For updating data update. In this one, I would like to update the quantity of photo glasses. So I want to change this 10-11. Again, you establish your connection to the database, create a cursor object, and then you execute, and here you enter the update SQL command. So update what you want to update is the store table. And which column do you want to update from the store table? So you want to set the name of column, which in this case would be quantity. And that would be equal to what? Guess what? Question mark. And then you say, where? Or let me show you how to update more than one column. So if you wanted more than one column, you'd use a comma and then say price equals another question mark. All right, so we say update, store and set quantity and price to this, but which row? So you need to specify conditional here. So we item equals to wine glass. Or you can also set this to a question mark. So you have three place holders here, and then you have the quote to close your cL statement, and then inside brackets, you want to pass the parameters quantity, and you have a second one is price and item. When you have more than one parameter here, you don't put a comma at the end, so this ends like this. You also want to pass these parameters here so they reflect your function input. So what we have here is we are updating the store table and we set the value of the quantity column and the price column to these values, but only for those rows where the item will be equal to a given value. So we give that value to this one here and the first two to these ones. You get the idea. Save the script and you need to call it here. So let me comment this out and update. So what quantity do you want to pass? 11, let's say. And the price was five. Let's say, it would go up to six, and which item you want to update? Water glass? That's it. Save your script and try it out. And we got these values updated as we expected. And that's what I wanted to teach you in this lecture. It could be more practical to actually have an ID here. So we say quantity and price where the ID is equal to a number, so we don't have to pass the entire name which can be confusing or it's prone wearers. So in that case, we would want to change the table here, and we would want to add a primary key that all increments. But you learn how to do that in the next section of the course. So there I'll show you how to make the real world program, and we will implement that in that program. So these were some trivial examples, and you get a much better idea in the next section. So next we will jump to postgrad SQL and we'll work with the cycle PG two library. Talk to you later. 165. PostgreSQL Database with Python: Welcome to this lecture. We are done with SQLite three, so I hope you were able to build this script that I showed you throughout the previous lectures. Because in this lecture, we are going to use this script, but I'll modify it so that it is compatible with interacting with post grade SQL databases. So luckily, most of the code is the same with some slight changes. Of course, we would need another library called Psycho PG two. And then we will grab methods from that library. And unlike SQLite three, psycopg two needs to be installed, so it's a third party library. It doesn't come as a built in Python library. So you need psychopg two installed, and you also need postgrad QL installed in your computer. So in this lecture, I'd like to show you how to install PostgraQL and psychopg two as well. All right. This is the official web page of PostgrasqL and you can just go to downloads here down here. And then you want to find your operating system. So PostgraquL works on Mac, Linux and Windows, Solaris as well. So I'm on Windows. I'll just click on Windows, and when you install PostgrasuL, you are also installing the PG Admin three, which is a graphical tool where you can see your databases. You're familiar with MySQL, PG admin is equivalent to PHB Madmin. Post grad QL also comes with a stack Builder, which is a package that you can use to download and install other post grad SQL extensions. So let's say you want an extension for spatial data, so to store spatial data in PostQL so that you can use it for JS applications. So there's an extension for that called Post GS. So anyway, I'll show you how to install extensions. First, you need to download PostgreSQL and I am on Windows, so I'll click this. And I'll wait a while until my download finishes. So I'll quickly go through the installation process. So I'm just being asked where I want to install Post grass QL, and where my data will be stored. And here you should be careful with these credentials. So your superuser, the ones who have most of the privileges to your databases, and your superuser name is Postgres, and I'd actually like to create a simple file. A text file just to store my credentials. I'd like to say the password as well. One, two, three. All right, so I enter postgress one, two, three for password. Then next, this is a port of your server of your database server. So I'd want to take a note of this too. This is about your local setting, so I'll just leave this default. And you'll just have to wait a while until the installation finishes. Alright, that was successful. Now, if you want to launch Stock Builder to install extensions for the post grade scale database, you may want to have this checked so this is my database server. And here you have a bunch of extensions that you may want to install, for example, spatial extensions, and you have Post gs for 32 bit and Post Gs for 60 for bit. If I click Next, this tells me that they need one package at least to be installed Let me just install Post gs. All right, agree to the Poss license and then just go next. This is asking me about DEL, which is another interface for GIS data. Alright, it was hard to install external extensions. If you want to go back to Stack Builder later, your Stack Builder should be here or you can just go to Postgres SQL, and here we have PG admin as well, and here is the applications tag Builder. All right, but if you want to work with Python, you want to access the PostgraQuL databases through Python, so you don't have to interact with these applications here. The way to interact with PostgrasQuL with Python is by installing Psycho PG two, and you can install psychopg two with PIP. However, you may run into problems because cyclopedia two is written in C, so you need a C compiler installed in your system on Windows, at least, you not have this problem on a Mac and Linux, I'm quite sure. The solution to this, actually there are a few solutions. One of the solutions is that you may want to install a visual studio on your Windows machine, but that's quite a big program and I wouldn't want to install that. So the second solution, which I prefer the most is to use pre compiled Python libraries. And you can find almost any Python libraries that require a C compiler. You can find those libraries in this page served by Christoph Goldke. So we're looking for SIP call. PG two. Here you have the wheel files. So a wheel file is a file that can be installed with PIP. So what do you do when you install something with PIP PIP install Psycho BG two. PIP is downloading the We file from a remote server, and then it installs it in your system. So here you can look for your version. This would be the file for my system. So just get this from here and paste it in here so that I can access it from the atom command line. So here is the file that I just downloaded. So just go ahead and pip install, and then you need to point to the Well file. So that will Oliged. And that was successfully installed. I can quickly check if that is available. And it seems to be working. You can also check the version of your library if you want. So it's 2.6 0.1. All right, so in the next lecture, we will connect to the database to the post gradsqll database, and then we'll be creating tables and inserting data, viewing, deleting, and updating them. So let's move on. 166. PostGreSQL: Selecting, Inserting, Deleting, and Updating SQL Records: Very good. In this lecture, you learn how to connect to a Post gradescL database and how to create tables in a post gradescule database, instore data, view data, and delete and update rows as well. The script you're looking at now though, is a script that you built in the previous lectures using SQLi database. So if you haven't watched those lectures, I highly recommend you to go through them first, then you come here. Because in this lecture, I'll just go through this code and replace only a few lines of and that suggests that the code that you use for Q three library is very similar to the code we will use for psycopg two, which is a library you use to connect to postgrascue databases. The main difference is that your database will not be a DB file stored in your file system. It will be a database embedded in your post grascule installation. And so the first requirement is that you need to have an existing database in your database server. Post grass SQuL comes with a default database. So once you install PostgreSQL, you'll have a database called PostgreS, so you can just pass the database here, or if you like, you can create your own database. So you just need to go to your PostgreSQL installation, and you can create a database through PG Admin. So here are your database servers, and this is a default one. You need to connect to your database server first. That this would be the password that you created when you installed Postgress. PostgresS 123 was mine. All right. So I was successfully connected, and I have three databases. So this is the default database that I was talking about, and these are two other databases I have created. So to create a new database, just right click on the databases and the new database. Let's say database one, and you need to specify the owner, so the user of your database. PostgressT is what I specified when I stall Postgres UL, this should be enough. Alright, so now you have a database here. If you click to that, you will connect to it. Now you can just close this and go back to Python. Okay, let me first comment these lines out so that when I execute the script, I don't get these function instances called. So we have an empty database. So the first thing we would like to do is to create a table. But first of all, I would like to change this too. Psycopg two. And of course, I would like to make a batch replacement of SQ L three, replace it with PG two. So I want all these library names here to be replaced with Pycopg two. So replace all and just press escape. That goes away. Luckily, this code is the same as SQLite three library. So we have connect and then we have the cursor object, then we have the execute method commit and close. All we have to do is change the parameters here. And here we would want to pass the database name, the user name, the host, the password, and the port number of your database server. And all that comes inside quotes. So it is passed as a string to the connect method. First, we have a database name. So the parameter dbname and that will be equal to a value. So you need to insert the value inside single quotes. So that is database. Well, the name of the database. Then you have user, and be aware that you don't need to use commas in here. So all this goes as a string and it is read as a string by the connect method. So user goes inside quotes, post grass, then we have the password, post grass, one, two, three, then you have the host name, so the host parameter. That should be local host. All right. So local host should be your host name and it's always like that. And lastly, we have the port number, and that goes inside quotes as well. So 532. So those are the parameters you pass to your connect method or the cycle PG two library. Then let's try to call that function. So create table is a function, and I'll save the script. So let me make sure you know what is happening here. So we connect to the database, and then we have the same methods for the cycle PG two library. So we are creating a table name store, and then we have three columns for that table. And we commit those changes and we close the connection. So save the script. Control S. Alan, call the script. And that looks successful. If you like, you can just go to PG at Mean. And here you can see the table that you have just created. So just enter the password, and you need to go to your database. So database one, expand that. Then you need to go to schemas, public tables. And this is our table name. So we have the store table, and you got three columns, item quantity and price. All right. We have an empty table, so let's go ahead and insert some data to that table. I'll just copy this connection string and paste it. In here. Then remember that we use question marks when inserting values for quite three, if you want, you could use string formatting placeholders. So so one for the item, one for the quantity, and another one for the price. Then after the comma, let me delay this. After the quote, sorry, you pass the percentage, so you already know string formatting, and then you specify the tuple of the variables you want to insert to. So item quantity and price. So you can use this, but this would be prone to SQL injections from tuckers. So it's not a good idea. I can go ahead and execute this actually just to see what happens. So let's say April and ten and 15 for the price. And let me execute this. So it looks like it worked, and we can check it in the table here. So you can just go to your database, which is database one. And here you can execute a simple SQL query, select all from store go to Run and you see that Apple was added to the table. So it works, but it's risky to use Python string formatting. So what you want to do is I'll just leave it for a while there so that you compare things out and to avoid scull injections, you should actually pass your variables as a second parameter to the execute method. So what does that mean is you don't have to use odes, so you just pass percentage S, just like that. Then you put a comma here so that means this string here inside double quotes is one argument, and then this one here is the other argument. Then you pass your variables, so that should work now. So I'm sure you can see the difference between this and this. And I'll just comment this out so that it isn't executed. And let's say orange. Same price and quantity execute. And let's go on check in PG Mad Man. So let me execute the query again. And you see that oranges added as a neuro to the table. So this is the way to go and I'll delete this. All right. Now let's look at the view function. So what the view function is doing is it connects to the database, and it selects all the rows from the store table. Then we store those rows in the row variable using the fatal method. Then we return those rows as a function output. Everything you need to change here is argument of the connect method. So just put them here. And it should be good to go. So let me view call the function and execute. And yeah, we need to print it. Forgot it. Yeah. So we got April and we got three oranges now because I just when I executed the script here, I got the insert function executed again, so we got two oranges and another one when you use string formatting placeholders. So you get the idea. Let's look at the delete. Function. Again, we need to pass arguments of psychopg two connection. Then we have delete from store where item, again, we can't use question mark, so we need to use percentages. And then as a second argument, we pass the item variable. So it's the same as cul three, but we use percentages here. And let me call delete. I'll comment this out and delete here. So what you want to delete is the item, what item? Let's say we want to delete rows where the item is equal to orange. So let's see how this goes. Yeah, the item was deleted. The rows with the item orange were deleted and we got the view function executed, so we got one row now. Our table has only one row. A quick look at the updates method now. Just like that. And here we are updating the store table, and there we are setting, so we are updating the quantity to this value and the price as well to this value where the item is equal to this value. All right, so we got one, two, three values and we pass three variables here after the comma. So as a second argument of the execute method, and the update method gets three arguments. So let me comment this out and update, we have only one row. So I'd like to set the quantity of apples to let's say 20. And the price, let's keep the price the same. And for the item Apple just like that and execute. And we got the quantity changed to 20. So that was it. I believe that was quite simple. So if you learned S like three before, this was quite simple for you. And if you have any questions, just feel free to drop them in the discussion section. I'll be happy to answer. See you in the next lecture. 167. App 6: Book Inventory App: Welcome to this new section. And in this section, you're going to learn how to build a real program that allows the user to store information about books. So I have already built that program, and I'll show you step by step how you can do the same. I have the program here, and it's an executable file. So apart from learning how to build the dot pi program, you'll also learn how to build executable files that run on Windows and dot app file that run on a Mac. So you can basically give your program to anyone and they don't need to have Python installed in their computer. So I call the program Bookstore. And this was built mainly with Kinte, which is a graphical user interface library, and the ASQ Light three library, which is a library to interact with ASQE Light database. So what we got here are four entries where you can enter a new book record. So let's say you got a new book in your store and you want to add it in your database. And here you can see all the books that have been added to the program. You can add a new book, let's say, Pythons for the title rdt quickly and 1918. You have the ISBN number, which is unique identification number for books. It's quite long. Let's say like that, and you add entry, and then you view all again and you'll see that the new entry was added to the database. So every record that you see here is actually stored in table inside this Light one database. Then you have some other buttons here. So if you want, you can actually search for entry for a record, search entry, and then it will display the entry that you search. When you click on the entry, you get all the fields displayed in each of the textbook here. Solve you all again, and you can also update and delete records. And finally, you can close the window. So it's not a great user interface. I'm not a great user interface designer, but you learn a lot by building this program. So it's quite a long one, but it will pay off. So let's kick it off. 168. Designing the User Interface: Hi there. And in this lecture, what you're going to do is start to build our bookstore program. Specifically, we're going to work on the graphical user interface because, you know, this program has two parts, so to say. So it has a backend and it has front end. The back end is the Sculi three database code. So the code that interacts with the database. And the front end is the code of the Tkinter library. So the code that builds up all these buttons, these entries, this text, and this list box, and this scroll bar. So normally you'd have to choose whether you want to work on the back end code first or you want to start building the front end code. First of all, though, the very first thing you want to do is actually to start defining some requirements. So you want to say what your program will do. So, let's say you want your program to show a list of the current records. So when you press VO, you see the list of records here. And then you want your program to search a current entry, and then you want to add Andrea and update and select data. And then you want the program to close the window. So basically, these are our requirements, and now you can choose to start writing the Beck end, so you could write a function that selects all the data from the database. Then you could return those data as text. So you can just print them out for now, if you want to write the back end first because you don't have the front end, you don't have the graphical user interface built yet. So you can just write functions of the back end and then print out the output. Or you can start writing the front end first. So you build this graphical user interface. But when you click those buttons, nothing happens. So basically, you just draw this thing with Python. And once you have done that, you start building the back end, and then you connect all the widgets and all the commands of these buttons with your back end functions. So it's a matter of preference whether you choose to work with the back end or the front end first. In this course, in this section, we're going to build the front end first. So we're going to build a graphical user interface that will do nothing for a while until we connect it with the back end. All right then. I would like to first remove this vertical bar here because I'm going to draw the graphic user interface here. So I'm going to make a sketch for you to see and to have the sketch in here all the time. So to remove this bar, if you're curious, you can just go to settings. Then there is a package that actually shows that bar that's called rap guide, and you want to displace all the displays a line of the eighteth character in the editor. And that may help you if you want may help you to keep a particular pattern. So you don't want to have more than 80 characters in your code. So that bar helps you keep that rule. Anyway, we don't want that, so I just removed it. And I'm just going to write a few notes inside the doc string. So you know that a doc string is like a comment line. So if you put anything inside these triple codes, this is not read as code by Pathon but it's just like a documentation string. So just for humans to read. So let's say I want a program. That's stores this book information. So title and author and ISBN. So the identification number for books. And the user can view all records. They can search an entry and add an entry, update an entry, delete, and they can close the program if they want. Close. Eight. So if you start thinking about that, now you'd want to have a graphic user interface that has all these buttons so that the user can do these actions through some buttons. And then you think about how they can view records. And you know that Tkinter has the list box, widget that allows you to display text as a list. So line by line. And then you want the user to search an entry at an entry update entry. So you need some entry widgets. And then, of course, you'd want some labels that can tell what each entry is about. So that would be a label widget. And you may also want a scroll bar so that your list is scroll so if there are many records, the user can scroll through them and they can see the records under the list. And so we've got a sketch. This, of course, requires some fantasy and maybe some experience with user interface designing. But it's very important that you have a sketch. So I'm going to keep this sketch on the screen while I code the program. Normally, in real life, you'd want to have drawing, maybe on a real paper or just on a digital screen. But it's important to have it, and now that we have it, let's start building it in the next lecture. 169. Coding the Frontend Interface: Great. So now we have a sketch of our graphical user interface, and that should make things easier. So now you can just go ahead and code your graphical user interface in Python using the Kiner features. Salt Kiner is a library that we'll be using to make this interface. And I suppose you already know Kinder because I explained that in one of the previous sections. So if you don't know Kinder, please go back two sections before this, and then you'll be able to understand what I'm talking about here. So I'll keep the sketch on the right. And now you know that to make a graphical user interface with Kiner, you can either use the pack methods to pack your widget or the grid method. We'll be using the grid method, so it could be a good idea to actually make a grid on your sketch. So that when you create your widgets, let's say you create a bottom, you'd want to pass the number of the row and the number of the column. So having a grid like this will make things easier. All right. And I just like to delete this doc string. We don't need it, and it saves me space so that you can see more a cleaner workspace here. All right. From skinerimport. Everything. So I'm not explaining the code now because you already know these things. If there is something new, I'll go through it. Window equals to TK, the TK method that creates a window object, and then you want to apply the main loop method, which is basically a way to wrap up all the widgets that you will enter in this space now. All right, so we have four labels here. So we have label title and author here and ISBN. So I'm just going to create fobels four label objects. So I'll name my objects, my variables from L one to L four and we use the object label method for that. Window is the parent window, and text should be title. So Control Enter, you can go to the next line, no matter where you are in the previous line. So you don't have to just switch, go to here, and then press Enter, you just press Control Enter and you go to the next line. L one, you apply the grid method. So the first label is row zero, column zero as well. Then you can just copy this and paste it three more times. So that would be L two, L three and L four. And you'd also want to change the text of your label. Here and ISBN. Author would be column two, as you see from the sketch. So 02, then we have the here would be one, zero, and then 12 for the last label. So let's see what we have. I'd just like to call my script. Alright, it looks promising. Now let's add the entries. So these were static widgets. Now we need to add some entries. So A one would be entry. And entry gets the window as the first parameter, just like any other widget does. And also a text variable parameter. This text variable parameter, this expects as an argument the value that the user will enter in the entry widget. That is a spatial data type. So you first need to actually create a data type here, an object of that data type. So let's call it. We are creating the entry for the title, say title text, equal to string vary. So this is the function that creates this spatial object. That would be equal to that title sex. So that's it. And you also need to grid this entry widget so grid. And the first widgets of the title widget corresponds with row zero and column one. So that's it. I can quickly multiply this here and author text here text and ISBN text. You also need to change the numbers or fewer variables just like that. And, of course, you need to pass that the user entries in here. So this should be and these two. All right. And lastly, you want to specify the rows and the columns for the entries too. So it would be zero, three, and then we have the text widget, one, one. All right. And the last entry. One. Three. All right. Let's check it out. Yeah. Looks good. Great. And now it's the turn of the lease box. So let's call it List one. Why not? That would be equal to List box window. And then you want to specify the height of your last box and the width as well. So I thought about putting six and 35. It would be good height and width. You can taste different heights and width and see what comes better. And then I'd like to grade this. Grid. And so this would start at row number two and column zero. However, if we leave it like this, things will not go as we expect. Actually, we can try this. As you can see the list box occupied only the first cell. So the first cell of the first column on row zero, one, two, so row two, column zero. What we want instead is to span these list box on the other columns as well and on the other rows because we'll have buttons here later, so we want to span that. And you can see the sketch here. So we can add row span parameter, and that would be equal to six column span as well. So that would be two. All right. So that would be a list box. However, we also need to actually add a scroll bar there so that the list can be scrolled when there are lots of data in the list, lots of records to attach a scrollbar to the list. The logic here works like this. You create your scrollbar, then you tell your scroll bar about the list that the scroll bar has to scroll. And then you tell your list as well who its scroll bar is. So let's first create the scroll an independent scrollbar. So let's say SB one. Scroll bar method. That is touched through the window. And then you apply the green method. So the scroll bar would be on one column three. And once you created these two objects, you want to apply a configure method to the lease box and a configure method. To the scroll bar object. And these configure methods get arguments. So this would be scroll command, equals to b one dot set. That's it. So meaning that the vertical scroll bar along the Y axis will be set to this scroll bar, and then you go to the scroll bar method. Sorry, this has to be configure, then you pass command equals to list one Y view. So that should work. You are passing a command parameter here, meaning that when you scroll the bar, the vertical view of the last will change. So let's see how this goes. And seems like I've messed up something here. I have put the position of the scroll bar on row one, I guess, and column three. So the scroll bar should be actually row two column two. Let's check that again. Yeah, seems to be working. Though it doesn't look very centered because we need to span it through the same rows as we have spanned the box here. So we need to add here a rowspan parameter and set it to six other scroll bar looks centered. Alright, so now, what we've left is to add these button widgets just here. Great. So we have six buttons. Let's start with the first one. We have the button method. Window and text, so buttons have text. A is the first one. And then I thought of putting a width of 12. So B one, gored. That would be row two column three. And we have five more buttons. So I'll paste this six, I think. So b2b3, four, at six. Of course, these buttons don't have a command parameter now because later we will add here command parameter, and that will decide what the buttons will do. But for now, that is just fine. So these buttons will be aligned in column three, all of them, and everyone has a different row value. And six. Great. So let's see what we got. And boom. I forgot to put a row number for the closed bottom. Seven. And now it looks better. So this was how to build a graphical user interface. Of course, these buttons don't do anything for now. So the next lecture, I'll show you how to attach actions to this graphical user interface. So we will work on the back end and we'll be using SQLite three for interacting with the database and fetching those data in this graphical user interface. So I hope my routines and my practices will help you to build graphical user interfaces with EZ and I'll see you in the next lecture. 170. Coding the Backend of the App: Hey, welcome to this new lecture. And here we are continuing to build our bookstore program that stores and retrieves book records from a database. So far as, you know, we have built the graphical user interface with kinder. So this is our script. So basically, we have the front end of our program. And now, so this is our graphical user interface. And basically what we need to do now is to attach some functions to all these buttons. So let's say, for example, when we press the view all button, a function will be trigger that selects data from an SQL Lite database and then gets those data and put them on this list box here. So that means we need to create a database, SQLite database with SQLite three. We also need to create a table first. So we could do this in the script, but I prefer to actually create another script and then import that script in here. So Import, let's call the new script backend. So we need to create a back end that Pi script. All right. And now I want to change the name of this off my front end script so that we keep the same pattern. So let's say front end. All right. So we are in the front end script now, and here we are in the back end script. So what that means is, let's say you create a view function, so that selects data from the database and you create that function here, and then you go to the view all button, and then you at command parameter here, and that would be equal. So let's say command just to give you an idea, command equals to back end and the name of the function. So something like that. All right. I hope this makes sense. However, for now, it would be great if we forget about this script. So we need to keep in mind the graphical user interface, but it's good not to interact with these widgets for now. So what we do instead is print out the outputs of functions, the functions that we built as strings in the command line here. So we'll not throw those data in the least box, but in the terminal here. All right. Let's start coding. Import SQLite three. That's the first thing you want to do. And I'll keep an image of the graphic user interface here so that it's easy for you to refer to it. So we need to create a view function. But before that, I would like to create a database, so a connection to the database. And I'd like to put that inside the function. So let's say function connect. And we have a connection object. So that would be a Scul three connect. And let's call the database books dot dB. All right. So we establish a connection to the database. Then we define a cursor object like that. And next, we need to execute SQL statement. So cursor object, execute and sit double quotes, we input the SQL statement. So we have a database, and we also need a table in the database where to store our book information. Now, think about that. User when you give this program to user, they will execute the program. And every time they execute the program, your script has to check if there is an existing table in the book's database. So if there is a table, you say, don't create the table. If there is not a table, you'd want to create the table. So create table if not exists. And let's call a table book, just to differentiate it from the database name. And then you'd want to pass some parameters. The first parameter I'd like to pass is the ID. So don't confuse this with the ISBN number. The book identification, this is just a number that will start from zero, and it will auto increment by one so that we have control of how many records we have in the database. So it's a good idea to have this ID here, that would be an integer, and you need to set it to primary key. So that's a mandatory column in your table. Then you have title as text, author, as text here as integer, and ISBN, that's an integer as well. All right, that's it. You want to commit the changes and then close the connection. All right, so we created a connect function. Later when we will run this script, so the front end script, and then you import back end, this script, the script of the back end. So the code of the back end will be read by Python. But if you haven't called this function, this code will not be executed. So what you want to do instead is have this function. Executed anytime you execute this function. So you execute front end and this imports back end, so it executes all the code. And this line here is executed. So the function will run anytime you run front end. All right. I hope that makes sense. Or let me quickly explain that better. So we have an A dot pi script, and we have B dot pi script. And in the A dot pi script, we import the B script. And what we have in the B script is a function PU that prints out something on the screen. Hey, and save this and save this as well. So so when you execute a dot pi, nothing happens for now because you have just defined your script. But if you call the script here, right, food, safe, and execute A again, this time you get the output of the function. So that's the idea. Thanks. And back to our real world script. All right. Now we have the connect function. Let's start by creating an insert function function that will insert some data in the database. So I'm starting with the insert function because that's an easier function than the other one. So I'd like to start from the easy things first. Dev insert. So that's how I call my function. And think about that you have four entries there. So you expect from the user to enter title author and year and ISBN number. So you want to pass four parameters here, and ISBN. All right. And then, of course, you need to connect to the database. Because this function here, it will just connect to the database temporarily, and it will check if there is a table and it will close the connection. So you have a closed connection here, when you press the insert button when you press at entry button, you need to create a new connection to the database. And let me go ahead and get these two lines as well because we need them too, right. And here is where we execute our specific SQL statement inside quotes. So what the Adentry button will do is insert. Into book, so table book values. And here is a trick now. We have an ID here, so this is an auto increment value, so we don't have to pass that manually. And what we can do instead is pass a new value here. And Python understands that, and it will create the ID automatically. And then we have four question marks, one for each of our values. Then you need to pass your parameters as a second parameter of the execute function. So as a tuple here, title here and ISBN. All right let me write another function, and then we execute the script to try it and see how it is going. So def, let's say the view function. So this will fetch all the rows of data off the table. So we copy this and put them here. So we connect to the database, create a cursor object, and then we execute an SQL statement. And then because this will be a select statement, so we will not perform any changes to the database, so we don't need a commit method here. And this is actually quite simple. Select all from book. So you actually need to return your selection as a topple. Then you grab that selection and you put that in the list box. So you want the view function to return a topple. So let's say rose, equals to cur fetch all and then you can close the connection, but your data will remain stored in the rose variable, so you can just return rows here. All right. So let's try out the script now. And the way to try it out would be to use a print statement. So we would want to call insert, and then we would enter some data manually. So in the real program, this insert function will be executed somewhere in the ad entry. Button. But for now, we need to keep things simple and reach our objective step by step. Insert, let's pass some values here title. Let's say the C and then author John tablet. All right. And here is an integer, so you just need to pass a number and ISBL so is an integer. So no need to put them inside quodes. And then you also want to print out the output of the view function. Great. So let's see how this goes. That would be the back end script. Great. So the record was inserted into the database and it was printed out from the view function. If you execute the script again, you'll get two records because the insert function was executed two times. All right. Seems to be going well. So what else do we have? We have a search function. And we would implement an or search. So what that means is that the user will enter a title or an author name or the year or the ISBN number, or he may choose to enter all of them at the same time. But if let's say he enters the year only, he'll get all the rows corresponding to that year. So here we need to pass four parameters as well. Bn all right. And then We need these lines of code, so connect to the database, cursor object, and then execute. So let's stay here for a while. We want to select all from book where title is equal to something or author is equal to something or year equals to something or ISBN. And then the second parameter would be the tuple of the arguments, phtalESBn. Then we need to fetch all the rows that will be returned from this query and store them in this rows variable, close the connection, and again, return rows All right. One problem here, though, that we may encounter is that the user may want to pass, let's say, the author name only to the entries. So this function will get only the arguments for the author parameter. These other parameters will remain without a value. And then you'll get an error because your function is designed to have four parameters. In that case, you'd want to pass some empty strings as default values. All right. And these two. So now, if the user passes an author name, let's say John Smith, this SQL statement will search for an empty title or for the author name John Smith or for an empty Ear and ISBN and so on. And it will return all the rows with John Smith as author name. Alright. So let's say this and try it out. So we have connect, insert to print view. Let's say the Earth. I'm inserting another record here. John Smith. All right. And then, let's say, print search, and you want to pass some arguments. For example, author equals to John Smith. All right. Without a quote here. And let's see how this goes. So we got here this list of rows from view function because we also have the view function here. And then the search function will return this row for us. So the row with ID three and with John Smith as author. So that is working well. Let's go ahead and build a Dilute function. So let's think about how the user want to delete a record. So most probably they would want to see some records in the its box. Then they would want to select one of the records. Let's say the record for ID three, the Earth, John Smith, et cetera. So they would select that and then press the delete button. So that means we want to first grab the list selection, so the selection from the list box, we would grab that as a tuple, but we'll think about that later. So we'll grab that as a tuple. That tuple has unique identification numbers or the ID. So we would want to refer to that ID and then go to our database table and delete the row with that ID. So hope that is not very confusing in the delete function, so we would expect the ID of the tuple that the user will select. And then we would want to have this code and start from there. So connect to the database, cursor object, execute a statement. All right. Let's see how this goes. So we want to delete from book where ID is equal to something. Great. And then that something is the ID parameter. So the argument of this parameter here, and this is the column name. So don't confuse this with this column name function parameter. Don't forget the comma here. And yeah, that's basically it. Let's save this script now, and let's execute it. We insert some data there. Let's say the sun this time. And so we'd have the C, the C again, the Earth, and the sun, so I'd like to delete the Earth. And I would want to put them in here, delete. So Earth has an idea of three. So we'd want to pass three here. Then we would view all the current records once we have deleted them. All right. So here are our records, and the Earth has disappeared. So it's working great. Again, as I said, this ID will be extracted from the table. So the tuple will have the ID as first item. And so basically we'll from Tuple, get the item with index zero, and we'll pass that first item to this delete function. Great. Function would be update. Update. And again, how do you want to update records? So how would the user want to update a record? Well, again, they may expect to select a row from the list box from the Tinder is box, and the values of that rod display in the entry widgets. Then from there, the user may want to change one of those cells of those entries and press the update bottom. So again, we will get the selection from the list box, then we would refer to the idea. So ID here as a first parameter, but we would also want to get the new values that the user would want from those entries. So let's say the user wanted to change the title from the sun to the moon, let's say, and you'd get that title. So the title will be in the entry box and pass it here. Same for author here and ISBN All right. And then you'd want to update your table. So update table where the ID is equal to this. Update table with this new values, where ID is equal to this. First of all, though, we need to get all these rows. All right. So update, book, and you say set. So the keyword set title equals to question mark. Same here, question mark, and ISBN equals question mark. So update book and set these values where ID is equal to another question mark. So then we pass a triple here. So ID, title, author and ISBN. So it's looking good. We commit the changes and we close the connection. And let's see how this goes. So currently, we have the rows in the table, the C, the C again, the sun. Yeah, these three rows. And let's update the sun. So I want to comment this out first and also delete. So let's focus on the update function and update. So you would want to pass the idea of the row so that you want to update. And then you want to pass the values in the correct order. So what you want for the new title, let's say, the moon. And then in the real interface in the graphical user interface, if the user wants to change only the title, he'll leave the other values as they are. So these values will be replaced to the existing values. So John Smith and year 1919 the ISBN number. But in this case, we are just in a taste mode so we can pass these values. Smooth. All right. And a number. So let's see how this goes now. And it seems it didn't work. The sun is still there. So let's see what we got here. Update Title Author here, ISBN, where IDs. So the ID should be at the end of the topple here. Hmm. B, you know, we put them in the correct order that we have set here. So let's try this out again. Hm. Now it's working. So the ID four was replaced to the moon, John Smooth, and the other values. Great. So I think we have the Ben script ready. And what we need now is attach all these functions to our buttons. So we still have work to do, and we'll do that in the next lecture. 171. Connecting the Frontend with the Backend, Part 1: Hey, welcome again. And this is the final push that we'll give to our application. So by the end of this lecture, you'll have a fully working program that can store and retrieve book records in an ASQE Lit database. So, as you know, we have two scripts. We have front and dot py, and we have the back end dot pi script. We are completely done with the Bend dot pi script. So we have built all of our functions that connect to the database and third view search and delete and update data. And now we need to go to the front end script because we need to tweak it a little bit so that the front end script is able to fetch to get data from the back end script or more specifically, is able to get the function outputs which are basically tuples of data. And then insert those tables of data in the list box. So basically the user presses a button, and then these functions are triggered and the data are inserted to the List box. So let's start from the easiest things. The first thing I'd like to implement is to get the records in the list box when the user presses the view or button. First of all, as I mentioned before, you need to import the Ben script in here so that you are later able to refer to your functions as something like backend dot view, for example, for the database view function. No, I have been mentioning that to attach a function to a bottom, you need to go to where you have defined that bottom. So to the bottom function, and then you add a command here. So command and then goes here goes the function. Now, if we just call the view function of the Bend script. So if we do Bent view view, all we are doing is just executing the view function, so we aren't inserting any data to the List box. So what we want to do is have another function and have that function, grab the data from the view function and insert those data to the list box. For example, let's call that function view command. Just like that. Remember, you don't pass brackets here because if you do when you execute the script, this function here, if you do like this, this function will be executed when Python reads your script, but you don't want that. You want that when you press the button when the user presses the button. This function is executed. So Tkinter knows that and if you just pass this like this, Python Tkinter will execute it when the button is pressed. So view command, and now you need a view command function. So let's write our functions just here. The view command. So think about the output now. The output we are getting is tuple. So I'm going to execute the view function here, so print view just to see what we have, if you have forgotten it. So Python Band dot pi. And so actually, we have a list of tuples. So topples inside the list. And what we want to do now is to insert each of these tuples. So each of these database rows as a new row inside the list inside the list box. So what we can do is we can iterate through this tuple. So that would be for, let's say, a row in back end dot view. So this is actually this list here. So this is actually an object and a list object. And then, List one, I believe, that's how our list box is coded. Yeah, so it's List one. That's a variable holding our lease box dot Insert. And then the insert method gets two arguments. The first argument is the index where you want to insert your values. So you have a list box, and that list box has several places. So it has the first place, and then the second, third, and so on. So if you want to put it in the first place, you enter zero. If you want to put it in the second, you would enter an index of one here and so on. But think about that. We are iterating through this tubles. So we go to the first tuple, and then we would want to put it, and we would want to put this tuple as the first item of the list. And then we would want the second to be put as the second item, and so on. So in such cases, the insert method also has a special index that is called end, and then you pass the row. So what that means is that the new rows will be put at the end of the is box. So you have this row and this is put the first one, and then this will be put at the end of the existing rows. So that ensures that every new row is inserted at the end of the list box. So I hope that is clear. And I would actually like to execute the script. So now we have the front end. Not pie. I have made an error here. So actually, I want to import back end here like that. Execute again. And we got the interface. So let's see what VO has. Name backhand is not defined in line five. So yeah, of course, it's not defined because I have a typo here. Bend. All right. Let's try it again. Close it. Let's see. Great. So we got the rows displayed in the is box. But when you press it again and again and again and again, these rows will be appended to the existing ones. So we need to think about how we can actually have an empty list box when we press the bottom. That's actually very easy to do. We need to ensure here that when these lines are executed, the list box is already empty. So what we can do is list one, delete and zero ensures that you are deleting everything from the index of zero from the row with index of zero to the end to the last row. So let's see how that goes. Ve, and if you press Vegain view again, you always get all the rows that you have in the database in the table. Great. Let's now go ahead and define a similar function for the search entry bottom. So the button is this one here, search entry. And again, we want the user to enter at least one value in the entries in the entry boxes, and then they press the search entry button, and then they expect the program to return the rows that contain the entry that the user input in the entry box. So again, you'd want to insert data in the box. So again, you can just call the search function or the Ben script in here command. So you need a wrapper function. So let's say search command. Another good reason that you want to use these wrapper functions, so to say, is that in some cases like this one here, you are passing some parameters to the function. So if you look at the back end and the view function didn't have any parameters, but the search function has some parameters. So that means you're not allowed to put brackets here, so you have to use another function where you call your main backend search function with parameters, actually. And that's what we're going to do now. So def search, command. And again, the search command, what we actually get as argument is title that the user will input an author name and here and ISBN number. Now, the way we're going to get these parameters is from the entry widgets. So where's entry entry entry. Here are the entry widgets, and you should remember that we have this string var object here. This variable that has the string are data type will be given as a value, the text or the number that the user enters in the entry widget. So keep that in mind. Let's go ahead here and the first thing you want to do is list one dot delete. So you want to empty the list. All right. And then you need to loop through the backend list output because, you know, in this case, let's execute this quickly, so the backend script. So we are searching for the author name John Smith, backend dot pi. All right, we don't have any John Smith at the moment, so let's look for John Smooth. So we got an empty list there. Save again, and you'll see that we got a list of topples. So in this case, we have only one tuple, but you get the idea. That means we need to iterate through four, row again in back end, dot, search. And here you need to be careful. So the search function has parameters, and the first parameter will be title text. So the text that the user is inputting in the entry widget, text entry widget. However, we are not done because the title text is actually a string are object, so it's not a plain string. And what we need to do is actually append a get method here, and this will output a string object. So if the user enters John Smooth fare in the widget, this will produce a simple John Smooth string. So I hope that makes sense. Author text again, get method. Then we have year text dot Get and lastly ISBN text dot Get. So for a in the list the search function will output for us when it searches the database, we simply want to insert new values at the end of the list, just like that. I can see the syntax highlighting is not working here, so I probably have some sort of typo. I'm missing a column here. So now four and in were colored in purple. Okay, so let's try out the front end script. And let's look for author John Smooth. Well, obviously, I press the view hole button, so I got everything here. So you want to press Search button. All right. Search search. And it always shows John Smooth. If you say view hole, it shows everything. So it seems to be working. And next is at entry bottom. So the user presses at entry bottom. They expect that the data they have been typing in the four entry widgets, this data will be stored somewhere. They don't know where, but they'll be stored somewhere and they will be able to retrieve them. So that means you need to call the insert function in here in the Bend script. So this function will get these four arguments. So the value around entry widgets, and it will pose them in the book table. As easy as that. So first thing we might want to do is go to the add entry bottom. So here, and then add a wrapper function here. At command. And then we create an Add command function. And this is quite straightforward, actually. You just say back end dot insert and here you pass these values. So I'll just copy this and pay some here. So let's try this out. Let's try to add some entries. Let's say trees and grass. Let's say been sand, year 1917, and just put an O there for the ISBN and add entry. So the entry has probably been added in the database, but we didn't see anything, and you can see it with a VL function, probably. So if I press VL, will see trees and grass. But it would be good that when we add entry, this entry, the new entry is displayed here so that the user knows that the entry was successfully added to the database. So here is trees and grass. And so let's go ahead and do something that the entry is shown in the list box when the user presses at entry. And what we can do is we first need to ensure that the list is empty. So delete zero to end the list. That gives us an empty list. Then we insert new values at the end of the list. So what values? Well, is one. So the values that the user will enter, just like that. So let's see how this goes. Let's say ans grasslands. Let's say Kirk met year 1910 and a number there. And this is not quite what we were expecting, actually. And we got this because we are inserting here many values indeed. So we are telling Python to insert all this in a new value, this in a new one, and this as well, and so on and so forth. So the solution here is simple. Just put it as a single value. So as a triple and run the program again. An error here, so we need one more bracket because this bracket here closes here. So just like that, try it out again. Let's say warm and Elena Gomez, 1944, and a number here. Add entry. And now we have the row in one single line. Fuel, and Wonder lens is there. Grass lens is also there. So let's move on. 172. Connecting the Frontend with the Backend, Part 2 ++: Okay, we have some more code to go. We have defined the view, the search, and the ad buttons. So now we have the update and the closed bottom. And I'd like to continue with the delete button because the delete button is easier to implement than the update button. So let me call the interface again. And again, think about the user. What the user might expect is that they may want to delete one of the rows, let's say, this row. So they expect to select this row and then they press the delete selected button, and this row will disappear from the database. And they may also want to when they select a row, they may also want to see the data in these entries, and we will take care of that, too. So we will fill these entries with the corresponding values when the user clicks one of the rows here. All right. That makes sense, I believe. And now let's look at the delete function in the backend script. So what Delete does is it expects for an ID, the idea of the row, and then this SQL statement then looks for this ID and deletes the entire row of the book table where the D is equal to this given D here. So what we need to do is when the user selects one of the rows in the List box, we need to grab the ID of that row and then send that ID to the delete function of the back end script. And then the delete function takes care of the row. Oh, good. And again, in this case, you would also want to append some sort of delete command function here, to the delete bottom. But in this case, I'd actually like to do a bottom up approach. So let's first think of how we're going to get the role selected by the user. So let's think about that first. And you don't know problem, but there is a method called bind of the Kinder library, and bind is used to bind a function to a widget event. So let me write that bind method so that you understand things better. So we are binding a method here to the list box widget. So it makes sense to write that method after we have defined the list. Widget. So we define the list widget here, and we configure it and then list one bond. And the bond method takes two arguments. So it takes event type, and also it takes a function that you want to bind to the event type. The event type here actually goes inside these characters, and it's called List box select. And then you want to specify a function here that returns a list object with a selection. So something like this. Actually, we will expect tuple in this case, a tuple with the ID, the title, the author, and the year and the ISBN number. So let's call that function, get selected Row. Then we go ahead and define that function. Let's define it in the very beginning here. So def get selected row. And this function now, because we have bind it an event to a widget event, this function gets a special parameter called event. And the event parameter holds information about the type of the event. So Python knows that when you pass this to the bind method, it expects the function to have this event parameter. And then. So again, this function will return to the selected tuple. But first of all, the way this works is that we first need to get the index of the list from the list box. The list may have, let's say, ten rows, and the first row will have an index of zero, the second an index of one, and so on, up to nine if we have ten rows. So to get the index of the selected row of the list box, we refer to the list box and then to the cur selection method of the list box. All right. And I'd actually like to just make a temporary return of the index here so that you see what this object is and how it looks like. So let's hope this will work. It should work. Python. Front end, yeah. And so, actually, we should have printed out the index here. We are just returning it, so Print index. Let's try this out again. So I expect to print out the index here, yeah. So this is the index of a selected row. So this is zero, one, sorry zero within zero, one, two, and so on. However, as you see, this is not a plain number. This is actually a tuple, a tuple with one item. So what we need to do is a very simple trick, and we just grab the item with index zero of the tuple, which is number two in this case, zero in this case, and so on. And then we might try this again, view all, and now we get single numbers. Great. So we're very close, but not there yet because we need to get the actual tuple with all the values of the row. And to get that, you need to apply another method called get so let's say the selected tuple. So the actual tuple that we want, the actual row that we want is equal to at least one that get index. So you can read it like this from the least box, get the tuple with index X. And then we can try this out. So what are we getting here? Don't get confused with this row. This is being printed out because in the Ben script, we actually have a search function being printed out. So this is printing the output of the search function. So this function is saying give me the row with John Smith as author name, and next time, this will not be executed. So back what we want to do is select a row and we get the row printed out there as a tuple. So that's great. So what's next? Well, next is we need to pass the ID of the selected tuple to the delete function of the back end script. We go to the selected button. Command equals delete command. That's how I'm going to call the script, and that should go here. D delete command. And what we have here is backend dot delete. Again, the delete method gets as argument the ID. So we have a tuple called get selected row, so we need to return return the selected tuple. So if we call the function now, get selected row selected row. And we need the item with index zero from get selected row. Save the script and we got an error at line 24. I don't have the column here. Try out again. View, and let's try to delete the moon. Delete. And Python is saying that get selected row is missing one required positional argument. That's the event argument. And so Python is right because here we have an event parameter, so we need to pass that as an argument. But here we are calling the function without any argument. So we're getting an error. On the other hand, we cannot remove this event because this function is also being executed by the bind method. So in that case, the hero of the day here would be a global variable. So you might already know that local variables, like the selected tuple is a local variable because it's defined inside a function. So if you print this tuple, Outside the function, select the tuple. You will get an error because Python will say, Oh, sorry, I don't recognize this. This is an undefined object because local variables make sense only inside the function. So in that case, we can use global variables. And the way to create a global variable is by using the global keyword and then declaring the name of the variable that you want to create. So in that case, if you print out the selected tuple outside the function, you get the value of the selected tuple, and the value of the selected tuple in this case would be the tuple with the values of the row. So in that case, we don't need to return the selected tuple because we can simply point to the selected tuple variable in that case, and we need to fix our delayed function here. So we want selected tuple and we want the item with index zero from the selected tuple. So let's execute again. And view all and let's delete the moon. Delete selected. View all and the moon is gone. So it seems to be working. Now, I'd want to fill the entries with a selected tuple or row, if you like. So we need to use the insert function of the enter widget, and we could actually write those methods inside the get selected row function. Because you know when the user clicks one of the rows, when they select one of the rows, we immediately want to fill those entries with values. And the first would be the title end and we want to make sure the entry is empty. So delete zero to end. Delete everything from the entry if there is something. And then E one, insert. So what we want to insert in the author entry. Well, that would be the selected tuple with index of one. So the ID has an index of zero. The third title has an index of one, and this would be the same for the other entries as well. So we have E one, two, E three and E four. And then here we want to grab the author name. Here we want the E and the ISBN number in here. Great. So I hope this will work. It should work. So view all select something, and insert method is missing one required argument. I think I forgot to put where I want to insert the new values. So we need here, here, here, and here. So let's see again, view all and now it seems to be working. So trees and grass and bends and so on. And let me try to delete this, delete, and the entry is gone. Great. So now let's go ahead. Without wasting any time, let's go ahead and implement the update function. So back to our backend script, the update function gets an ID and title author and ICBM. So unlike the delete function which only got one item, this gets four items, five items, actually. So in the delete command function, we pass the selected tuple with an index of zero. Now, the update function will be similar similar structure, but then we will have multiple arguments here. So we have ID tile author and ISBN. So selected tuple with an index of one, selected, tuple with an index of two, selected, tuple with an index of three, and selected tuple with an index of four. And then we need to add that function to the update bottom. So update command. Alright. And I forgot to change this. Update command. This should work. So let's see. I've forgotten to pass the name of the parameter here. So command equals update command, save and execute again. Let's try to update this row. So let's say nine. An press update selected. And yet another error don't get scared about errors. The more errors you see, the more familiar you become with Python. It's important to focus on the error, see what line you're getting the error and try to understand the type of error and the message you're getting. So in this case, delete takes one positional argument, but five were given. We didn't execute a delete function here. We executed the update button which gets an update command function, and you go to the update command. So the update command B and delete. So that's why we are getting this error. The update command is actually executing the delete method of the Bend script so we want update instead of delete. And save the script and execute again. View all. I want to really update this number here. So nine updates selected, view all, and it's not working. And in this case, we're not even getting an error here, so you may feel lost at the moment. So what you could do in this case is check what you are returning in your update command function. So you know that you can isolate problems by using print statements. So let's say you want to check what you are sending to the update function. I know the problem here, but just to show you the way you can troubleshoot things. So print out and execute this again. We all get the grasslands updates selected. And you see that the tople is being printed out as it is. So this number is not changing. Actually, I didn't change it. So let me change this again. Let's say 24 and update selected. And so you see that the number 24 is not being printed out here. So that means we are sending to the database. This record, again, so we're not sending the updated record. So why is that? If you have already found it from earlier when I wrote this function, that's very great. If you haven't, well, the reason is that we are sending to the update method, the selected tuple. And the selector table is the one that the user has selected. So it's not the actual entries that the user is sending to the update command. So in that case, we actually want to send out these values, so the current values of the entries. So I'll copy this and paste it here. Okay. And the first selected tople is the ID, so we want to keep the D of selected row because the user is changing the other values, not the ID. And this looks fine. The bracket closes here. Safe. So delete this one, safe, execute again. We go to this and let's say three, update selected, V and three is there. Delete, view all, it goes away. You can add it again because you have it in your entries, at the entry, and it was added again, and you can see it here. So everything is working great. And we want to close this program, but we closed button, it's not working at the moment, so let's go ahead and implement that as well. And that's very straightforward. You just go here and command Eagle two. So you want to destroy the window, right? So window dot destroy. That's it. Save the script. And try it out. So they are working as usual, close and the window closes. And you may also want to put a title to your window and use the WM title method of the window object. Title. Let's say book, store. And you should see that name in the title bar. So finally, we are done with this program, and I know there might be things to improve, and I'll welcome any suggestions from you so that we could improve the program. Programs have versions of this is version zero, you could say. And I hope you found this very useful and learned a lot from this. So I'll talk to you later. 173. Creating .exe and .app Executables from the Python Script: Hi again. So we have this great program that works very well. And it consists of three files. So two Python files and one dot DB file, where the data is stored. This is good. We can execute the scripts like this. So using Python, and we get the program displayed. But I think of if you want to give your program to someone else, you can just tell them, Oh, install Python and you can execute the program by going to the terminal and invoking Python and script. So that may get terribly difficult for users who are not experienced with programming. So in that case, you want to make a standalone executable program that you can just sent to anyone, and they can just double click it and go ahead and insert data and retrieve data and so on. So in this lecture, I'll show you how to make an executable file, and you make that file, whether you are on a Mac or Windows or Linux. So the code is the same. There exists a great library to make standalone executables. That is the Pi installer. So you can install Pi Installer using PIP And now it's terribly easy to make a standalone executable file out of your Python script. All you have to do is call Pi installer and then point to your script. So in this case, our main script is front and dot py. So that's a script that is holding all the code, and it also imports the back end script. So we want to point to that file. And if you leave it like this, you'll get dot X file if you are on Windows, afile, if you are on a Mac. And together with those files, you'll also get a bunch of other files that are associated with your program. The benefit of that is that it gets easier to troubleshoot any errors that you may get. So you have lots of files and then you can go to those files and find the error and so on. But if you want to be practical, you'd want to pass a parameter here. Called one file. So that will create a single executable file for you. And in this form, you'll also get terminal command line displayed on the background of your graphic user interface. So if you don't want that, you can specify another parameter called windowed like that and execute. And you'll have to wait a while. And my executable was created. So if you were on a Mac, this would be a file. So mine is here at the disc folder. So in this folder, I can look up here. So front end dot x. If you execute that, you get the window. And as you see, you also got the books that DB file generated. So by default, this only creates executable file. Then when you execute the program for the first time, remember that we had a connect function in the backend script. So that function creates a database. So that's what this did. And if you view all now, you don't have any rows, so you don't have any data because this was created from scratch. So in case you want to have the existing database, you'd want to give to your user both the executable file and the existing database that you have. So, for instance, let's say this doesn't exist, and I can go to my existing database, and if I put it here, so Python knows where to search for the database. Now if you view all, you'll get the data from the existing database. And we can make a quick test. Let's add a book, the great short D Taylor year 1913 and put a number there. At the entry, and the entry is added to the database. And you can close the program, and that's it. Hope you enjoy this. I'll see you in the next lecture. 174. What is Object Oriented Programming (OOP): Hi, and welcome to this new section where you learn about object oriented programming, often referred to as OOP for short. Now, if you have experience with programming, that's probably a familiar concept for you because OOP is used in most of the languages. But I assume you don't know anything about object oriented programming, so I'll explain the concept from the beginning. Now, there are various definitions of OP out there, and some get very tricky. But I believe the best one to know is that object oriented programming is just a way to organize your code. That means OOP is not a must. So you can simply use functions to build an application as we did here with our bookstore application, and many programmers choose to not use object oriented programming to organize their code, so they don't use the OOP way to write their code, in other words. However, it is generally accepted that if you have more than two functions, which apply operations to the same object. For instance, a program that applies operations to a Kiner interface. So you have these callback functions. And so you should organize these functions into something called a class. Now, because object oriented programming is a complex concept, I didn't include that in the beginning of this course. So I wanted that you first build some applications using functions, which is more intuitive, then you move to object oriented programming. So back to our graphical user interface application. So the object here, I'm talking about objects, and the object here is the entire window with buttons and other widgets as well. Now we can put all the attributes that define this object, so this window, such as the title of the buttons, the labels, and also the callback functions attached to this object inside a class. So in our application, we didn't use classes, we use functions. So this script here does not apply to object oriented programming, and putting this object inside a class means we're organizing the code in a class, which creates an object, so that's why we call it object oriented programming. And using classes to organize your code is referred to as object oriented programming. And what I'll do next is in my back end script where I have the database operations. I'll transform this script by putting this inside a class. And after that, you can do the same for the front end interface so that you practice object oriented programming. Now, my purpose here is not to train you how to write classes. I first want you to understand classes, and many learning resources explain object oriented programming by saying something like, we create a class that creates a dog object, and a dog can heat and bark and so on. That's a good example to train to learn the syntax of a class. But hey, what is a dog in programming? I mean, you can scratch your head the whole day trying to come up with a scenario where you'd have a dog as an object in your application. That's still a good example, but only if you have some years of experience in programming, and you can quickly think of where and when to use classes based on such examples. I assume you don't have these years of experience, so I'll use real programming objects in this section to explain such a tricky concept as object oriented programming. So the best way to understand OP is to first build a program with a known object oriented programming approach, so using functions, and once you know that program well, then you build that program again, using OP, and then you automatically understand what OP is by looking at how things are different. So let me organize this code using classes now and later we'll build a simpler program from scratch, where we create a bank account object with Python, and we will apply functions to that object such as withdraw deposit, and so on. Oh, that's great. And, yeah, that's about this introduction. And let's move on to the next lecture and write some classes. 175. Using OOP in a Program, Part 1: Good. Now I'll go ahead and transform this script into an object oriented programming style. So in other words, I'll organize these functions in a more efficient way. And just to refresh your memory, what this script does, so we have a back end and front end script, and the front end, what it does is it constructs the graphical user interface, so you know that. And we have these books DB database file, and there are some data there. And you can search for entries for rows in the database at New and so on. And this front end dot pi constructs the graphical user interface, and this back end is responsible for the database interaction. And so object oriented programming is about encapsulating functions inside a class so class and let's call this database. And yeah, that's it, basically. We still have a lot of things to do, but let's think about what is this database class. Well, whenever you decide to use object oriented programming, you first need to think about the object that you want to use, which is the object that you want to apply these methods to. And in our case, that would be the database. And so then we insert data to the tables of this database and view data and so on. Of this object, this object, you first need to create a minimal object when you call the class. And I'll show you how you call a class in a minute. But for now, let's focus on creating the blueprint of the object. So you create the blueprint of the object, which is this one here, and then you create object instances using that blueprint, and you do that by calling the class. Now, when you call the class, you want to have this minimal object. So in this case, that would be to establish a connection to this database. And then create a cursor object and maybe check for table so that you make sure that your database has a table so that it allows you to later apply methods to this table of database. Otherwise, the database would be useless. So it needs to have a table and an established connection. That means you have to figure out a way that when you call the class, these lines here are executed. And Python has reserved a special syntax for that. So the first function of your script you need to call it it with double underscore in front and on the back. So that's an init function, which means initialize an object. In other programming languages, that is called a constructor, so it constructs the object. So when you call a class, this function is executed, but not the other ones. The ones are executed if you refer to them, in this case, that would be something like database dot insert, and then you pass the parameters, the arguments there. Now we have quite a few things to add here in the script for this to work. But I would prefer to do this on trial and error basis. We execute it will see what error we get so that you understand how things are working there. What I'll do, I'll call this class as it is now. So we don't need this function. This function is gone now because I replace that with it. So you don't call functions anymore like we did here. So, for instance, here we are calling functions from the backend module, which is like a module, you are importing this as a module. And in this case, what we do is from backend, import database. So we import the database class from Becan script. So that makes available the database class for us. So the database blueprint. So this is just a blueprint. Now we need to create an object out of this blueprint. So let's call that object database. Thath be equal to database. So the class and for now, let's not pass any arguments there. Then we need to replace these references so we don't do backend anymore. We do database that view. So we are referring to the view function of the database object, which is an instance of this class. Great. So I'll go ahead and replace these other ones with database. So back and replace that, replace, replace. Yeah, that's it. This is the script name, and it should be like that. Escape here. Great. Now I'll go ahead and execute that. So don't expect this to work, but we have to look closely to the error, trying to understand what it says. So trace back file fronten dot pi Line four. Here. It takes zero positional arguments, but one was given. And what's happening here now is that when you call the class, this class will create an object instance and store it in this variable. And then it sends this object instance to this function. So let me split this on the right so that we have both the scripts in here. So the front end and the back end. So basically, this database object instance is being sent to this innit object. Even though this is an empty bracket. So that's like a hidden syntax there. And to fix this, you need to perform a trick here. So it says it takes zero positional arguments because actually it has an empty bracket here. So it's like a normal function and functions if you don't put a parameter there, but then you pass a parameter when you call it. The function will say, I don't take any positional arguments or any mandatory arguments. But one argument was given to me, so I'll throw an error. Now to fix that, you need to pass a parameter there. And everyone passes self there. So you can pass any word that will still work. But as a convention so that your code is readable by other people, you need to pass self. So now your init function takes a parameter, and when you call this class, this class will send the object instance, and that object instance will go inside this parameter. So this parameter will be replaced by the object instance argument. Great. If you still don't understand that, I'm sure you'll do so later as you write more classes. Good. Now, I'll go ahead and save this and this and try out the script again. And great. So that means the class was successfully initialized, and it created an object instance for us. Now, let me close this and maybe add something there. This is not necessary, but just to show you that if you want to add more parameters to your init function, you do something like DB and then replace this with Dib and then here you pass the argument that will be passed to this DB parameter. So that would be books dot dB the file path to our database. Great. And if you execute this again, you get the same result. So what's happening here is that Python is for sending the database object instance to the self parameter, and then it sends the path of the file to the DB parameter, and that DB parameters sends that path to the DB parameter of the connect method. Great. Now let's see how these methods will work. So we have the view button, which if we press it, what will happen is the view function of the database class, actually, the view method of the database class will be executed. So this one here, let's see if we are able to get it. Well, arn error, let me close this. So it says view t zero positional arguments, but one was given. So that again suggests that when you call a method of class, the class is sending the object instance to that method as well, just as it did with init function. That means we need to do the trick again. Pass el there and try out again, see what error we get this time. Well, no error. Things are working, obviously. So that's great. However, if you try the other methods now like insert, you'll probably get an error. So let me try that. So if you all, it's working fine, but if we insert something, let's say hey there and and yeah, at entry. So insert takes four positional arguments, but five were given. So insert. And these values are being passed to these parameters, but also we're passing the object instance. So let's go ahead on self there, and I'll do the same for search as well. Delete and update. Yeah, that's what we have. Looks good. Let's try out again. So view all and Add entry. Yeah, this seems like it's working. View all and here we have either Close. So we were able to create a class and put all the functions inside the class. So we have an organized program now. And so that's object oriented programming, but object oriented programming is not simply about putting some functions inside the class. Object oriented programming is about good design. So this script is not probably the best design that we can come up with why is that because we're not making use of the real advantages that we have by using classes. So what I mean is that here we are creating these methods, and in each method, we're executing some close functions and also creating a connection in each of the methods. So we can reduce this code furthermore by removing the repeated actions. So in a class, what you need to think about is a way of constructing something at first, in the init function. And then you refer to that something in the other functions in the other methods. So we're talking about methods here. So even though our script is working fine, in the next lecture, we will go ahead and improve the design of it. So I'll see you there. 176. Using OOP in a Program: Good. We were able to transform our script, which was built using functions, and we created a class and put those functions inside that class. So they are now called methods. And while this is a use of a class, it's still not the best use of object oriented programming paradigm. Because we have a database here, a database object that is being created, but we are not treating it as a solid object, so we are opening it and closing it in every method. So what I'm thinking is we create a connection when we call the class. So when this function is executed, we create a connection there and we keep that connection opened. So I don't include this close method there, but I leave the commit method in case there is no table, and a table will be created, and the changes will be committed to the open connection. Now, because we have a connection open there, we don't need to establish a new one in each method. And we don't even need to create a cursor object because the cursor object is being created in here. So we get rid of those two lines in every single method. So in view, we have a cursor object when we go here, and then we execute this statement to that cursor object. So that is good. Then we go down here, these two as well. And for the delete method. An update as well. Great. Now, let's see how this goes. Let me make this closer. So we call the front end script where we are creating an instance of our object. So far so good. View all. And it says that a name curve is not defined in line 17. So we executed the view method. And what the view method does is it tries to find a variable declared variable inside the function. The curve variable, it doesn't find it, then it looks if there is a variable outside the function and it doesn't find it. Actually, there is a variable that has been declared in this init function, but this is a local variable. This has value only inside this function. You cannot access this outside of the init function. But if we refer to the self argument, which is the database object and see what we get. Let me close this. Save that works and view all, and now we get another type of error. And it says attribute error. So let me close this. So look carefully here and it says database object has no attribute curve. That's in line 17, so this one here. The database object, this one is this one here. So self has been replaced by database, which is the object created by this class. This is an attribute of this object. And to fix that, we need to create an attribute there. So we say self dot cursor dot cur, Eagles connection dot cursor. So the cursor method of the connection object of the QSt three library. Now if we try again the code, it says name curve is not defined in line eight. Now that we created an attribute. This is trying to find the variable curve, the local variable curve, which is not in this function because now this is an attribute of the class. That means we need to refer to self here as well, to the object and then curve execute and so on. So if we try this now, we get another line curve is not defined in line 18. So here, that means you need to do the same and we don't have any curve variable anymore. We have the cur attribute. So now if I run this again, I'll get probably error about the connection this time, the con variable. We all is not defined in line 19. So again, this view function is trying to find the variable con connection, so self commit there and here as well. So you declare the attribute there and there you commit the changes down here. And self connection close. So that looks good now. A rose equals to this. So rose is just a local variable that is created here, and then we return the fetched rose from this expression. So this method returns this when it is being called in this script, just here. Good. And yeah, let me try what we have at this point. Mm line seven name C is not defined. Oh, yeah, we need to do the same for these two, and everything looks good now. So let's try again. Yeah, view all, and now we get the data there. But when I press it for the second time, we get yet another error. And so it says cannot operate on a closed database. So why is that? Well, I pressed the view button once, and this method was executed. So the cursor object was able to fetch this data, and then we closed the connection. I returned the rows. So we were able to get those three rows there. But then when I press the view button for a second time, the view method faces closed connection. So that's why you get this cannot operate on a closed database error. So and see what we get. So view all, it's working well. Yep. That means we can go ahead and modify the other methods. So self cursor and self connection and remove the close. Let's think about closing the connection later on. So don't focus on that now. Just try to make these methods work, self here, self there, and there. Again, for the Dalit method, y remove the connection close. And everything should work fine at this point. So let's see if we all this is working. Let's search for something. Let's see and search entry. Oh, we got one cursor there. So curr is not defined in search. Oh, yeah. Sorry. Okay, again, we all all let's see search entry. And yet another name error. The name rose is not defined. So by mistake, I converted this local variable to an attribute. So rose here, rose there. Okay, one more time. We all and now it seems to be working. So let's add some data. Add entry there and cannot operate on a closed database. Oh, why? Mm. Because in the search method, we have a closed database, so we close the database there. And I overlook that, so we don't have any more closed methods there, no. So let's try one more time, then. Sorry about that. Add entry, and now it seems to be working fine. Great. So everything looks good, except we don't have the closed method anymore because we can't keep that method in the methods of our class because you saw that when we have that method there and we end up with this error. Or you can leave the code without closed method. But you'd end up with some problems later because if you have some methods that have not been committed, then when another program connects to your database, then this data will be committed. With the next operation. So it messes some things up sometimes. So as a rule, you should close the connection. And to do that, there is another special method that you can add to your class like this one here, but this other one is for destructing your object. That is called deal. So for delete, and this also gets the object instance as a parameter. So this method is applied, is executed when you call an instance of the class like we're doing in the front end script just here, while this one here, this is executed when this instance is deleted from the script, which happens to be when the script is exited. So before the script exits, this method will be executed. And what we want to do here is self dot connection dot Close. So that should do the trick. Now, if we try out this, we should get the same results. So I added this by mistake, but anyway, so we'll see you can search for that and you get the rose with that particular value. So this is my solution, and there's no standard way to write a script. So there may be other alternatives to solve this problem to build this application. So you may also choose to add a method there or here in the graphical user interface. So you could do something like you add a button, like Commit button, and then here you add another method called Commit. And then you remove probably all these commit methods from these methods from methods of your escult operations. And then you put that method. So one method commit inside that commit method of your class. So when the user press is committed, then you commit the changes to the database. So that would be another solution, but this is what we came up with in this particular case. So I hope you understand a few things now, and this is rarely used. So normally you only have to use in it and then the other methods. But this is appropriate when you want to apply something just before exiting the program. So that's great. And in the next lecture, I will write another class. So we will think about how to model a problem, which is about creating some sort of bank account object where we restore a balance of money. And then we withdraw and deposit money into this balance. Now, as an exercise, you can convert this script, sold skiner part of the program, the front end into an object oriented form. So you put this inside a class and try to come up with a good solution. I'll also provide you a solution to this. But before that, I'd like you to try out yourself so you practice object oriented programming a little bit. Yeah, that's good with that. I'll see you in the next lecture. 177. Creating a User Login Page: Hi. In this lecture, I'm going to show you how to create a minimalistic mobile app using Python and its Kivi library. What we are going to create is this one page app that you see in here. As I showed you in the previous video, this app is actually a multi screen app. So when you click Login, you go to another screen and then sign up to another screen and so on. But in this lecture, I'm just going to show you the minimal app, and that's like a template that you can use to write any other apps, no matter if they have one screen only or multiple screens. So I'm going to keep this screenshot here on the screen. Because this is necessary when you create the interface, the graphical interface so that you code by looking at your design. This could also be in a piece of paper where you have drawn a sketch of how the interface looks like. So what you need is a Python file. That's how everything begins. And I'm going to name my file main dot pi. You don't have to name it main dot pi, but it's a good practice because later on when we deploy our app, when you convert your app to an executable mobile app that runs on a real mobile phone, you're going to have to name your file main dot pi. So it's a good idea to name it right now, so you don't have to rename it later, or maybe you forget later and you get some errors. So main dot pi. This main dot pi is where the logic of the program will be written in Python language. And there's also another file you need to create. You can name it whatever you like, but I'm going to name it design KV. So you have to use the KV extension and separate the screen. I'm going to put this in here. Mine that pie in here, and I'm also going to show you this picture down here to keep it there. And mean that pie should stay here. All right. So what is this KV? Well, nothing to worry about. It's actually a good thing. There are two ways to create a mobile app with Python and the Kivi library. The first way is to write everything in Python, which means the logic of the program. So the processing and everything that happens on the background with the data you process is the user logins, retrieval of weather observation data or wherever your app does. And the other part of the program is the graphical user interface, which is this thing here. So some sort of language, you need some sort of language to to say, Oh, a label with this font size and this font family and this textbook and so on. And you can do that in Python, but that is not a good practice. It's a good idea to write that graphical interface in dot KV file in the Kiwi language. But Kiwi language is very, very simple. You're going to learn it in one day. So I'm not going to show you how to make both ways. So I'm not going to show you how to make an app using both methods, which means the method of having everything in the dot py file and the method of having the logic in the dot py file and the graphical interface in the KV file, I'm just going to show you the right way, which is using Python for logic and KV for the graphics. That's what every professional uses. So please learn this way. And we start from the Python file. The first step is to import all the necessary objects from KV. From qv dot App Import app. This is the main object. It symbolizes the app from KV Lang Import. If you were wondering how you connect the Python file with the KV file, the answer is this Builder object, which I'm going to show you in just a minute after importing one more object from qv dot UIX screen manager, Import, screen manager, and screen. And that's it. And then you use the builder that load file method, and there you load the design that KV file. So that's how this script will know about the KV file. Make sure these two files are in the same directory, main dot pi design dot KV. And then you go to your KV file. The way the KV language works is in hierarchy level. So it's an hierarchy of objects. So this is a screen and this screen has widgets inside. So if you have only one screen, you're going to write. Just give a name to the screen and use these symbols, and then a column there. So I'm calling this screen the login screen. And then if you have another screen, let's say, when you click this button, the sign up screen shows up. Then you want to write another screen like sign up screen. Same way. But for now, we're just going to have one screen. And if you're wondering, how did I get this purple, nice color? Well, this is syntax highlighting for Kiwi language, and you can use an extension, the Kiwi extension. So just search for Kiwi and use this extension. So install it and then enable it. And you're going to get syntax highlighting in visual studio code, which is a good thing. So then the login screen has widgets, I said. And once you press Enter, you want to indent with a tab or four spaces, just like in Python. So the first widget is so the first widget is a label. But instead of doing that, you want to add another widget on top of the label. It's an invisible widget, but it's still a widget. It's a grid layout. You don't use these symbols anymore. You just use it for the screen. A grid layout, what it is is basically the type of area, which will have all the other widgets. So down here, we're going to add the other widgets, and it's a way to separate the area. So the screen. And the way I think I'm thinking of separating my screen of organizing my screen is by having a main grid layout that will have every thing, and then this grid layout will contain two other grid layouts. Grid layout for this area here. And this particular grid layout is going to have one column and an undefined number of rows. So you can add as many rows as you can in this grid layout. So what I mean is grid layout, and then another grid. Layout. So the first grid layout is this entire grid, which will have one column only. And this grid layout is made of two grid layouts. This one in here, and this one in here. So this one is and that is that. The reason I flit it this way is because this area here has widgets which are organized in the same way, which means we have only one column here. And here we have two columns. So in this second grid layout, I'm going to declare cult two, the attribute. And here, by default, these grid layouts, they have only one column. So I'm going to leave it as one column. And then what you add here is labeled. That's the first widget we have here. Enter and then tab, so everything is indented. Text of the label is in quotes, user login. Then what we have under the label is a text input. The text of the text input. That's not what we want here. What we want here is hint text. So that's username that you see inside the textbook is like a hint for the user. User name. And so here we are adding widgets as a rows for that grid layout. Then we have another text input with hint text. Password. And then we have a button with text login. And then we go to the other grid layout. We have two buttons here. With the first one has a text forgot password, and the other one has a text, sign up, and that's it. And that's all you have to do for now for the login screen. Now, there's also something else here you have to do. So go to the first level of indentation, the same as login screen. You see here. Just there, and you want to add another rule. So in the Kiwi language, these things here, in the symbols inside these symbols are rules. This other rule is the root Widget. So it's basically an invisible widget that keeps a record of all the screens of the app. And in this case, we only have login screen. And this login screen has to have a name. So let's say login screen in quotes. You're going to see later on that we're going to need this name when we refer to the login screen from within the Python file because the logic will be written in Python, where you say that if the user presses that button, we're going to say something like screen that current equal to login screen. So we're going to give the name of the screen that Python is going to show when the user presses that button. And that's all we have to do in the KV file. Make sure that you are not using assignment operators instead of columns. So use columns. I used to do this mistake when I was learning QV language because you are used to Python where you use assignment operators a lot, have a look to your file and then go to Python. And what we need to do in Python now, we need to create some empty classes which have the same name as these rules in here. Which means class. Login screen use the same case. So I use L and S in here, same as here. So it has to be the same string, exactly. And this string has to inherit from the screen object. So it's going to be a screen object. For now, let's say just pass. And then you have to create another class, which is, you guessed it, the root widget. Every rule here has to be represented by a class inside Python. The root widget has to inherit from screen manager. So don't worry if this code is a bit rigid for now. So you have some rules which seem like a black box. But think of it as just a template. You're going to use this template for every app, so it's a good thing to have so pass for that, too. And lastly, this is the last thing, I promise. You also need the class main app. So this is about the app object that we haven't used yet. So this has to inherit from app. That's one and this needs a method called build. Self. So every method needs a self parameter. So this build method is actually a method of app. You can see that if you use here. So I executed that line and dear app. You'll see built is among those objects, those methods there, build. Alright. And so that built method is going to return the root widget. But make sure that is the object and not the class. So we are initializing the root widget in here. You can see I'm using the round brackets. And the very last thing is, if and once we have done that, this is the app now. We are ready to execute. But as you see here in the Python file, we are not calling any class. So the very last thing we need to do is, of course, call the main app class. A good practice to do is to use if name equal two. Main. Then you create an instance of the main app and then use the run method of the main app, which is, by the way, it's a method of app. So you can see a run also in here, just there. Save that script, and I'm going to execute now the file and see what we get. I expect, of course, to get some errors because I don't think I did everything 100%. Yes, I didn't get an error. Everything is fine in the terminal, but the interface doesn't look as I expected. So I have made some mistakes there. So sometimes you don't get an error in the terminal, which makes it harder to troubleshoot the problem. And if you don't get an error, where it should look is the code in your Q file. So in this particular case, it looks like the grid layout is not working as it's supposed to be. And the reason for that is that I didn't specify how many columns the grid layout should have, the main grid layout, but also the other one, the child of that parent grid layout. So before making a change, you need to close this window. I'm going to go here. So I'm going to pass a cult attribute just like I did with this grid layout. So let me just test it with that parent grid layout first. So this is what we get. As you can see, compared to this, we are not seeing the first grid layout elements, which is a label, the username, password, and the bottom. Because these widgets are actually hidden inside this forgot password bottom. So they are somewhere in here. In the corner. So when you don't specify these columns, how many columns you have, Kiwi will just stuck all the widgets in the lower left corner. So if we close this now and we also add a calls attribute equal to one, and if I don't save it and I run this again, I'll see the same output. So I need to save the script, Control S, and then run it again. And this time we see what we were expecting more or less. Well, we still need to add some padding and some spacing between the widgets to make it look like here. But this is what we get so far, and I think it's good. So I'm going to close this now and consider this code as done. But before I close the video, I'll make sure you understand what is going on in here. So this Kiv file, all these things you see here, grid layout, login screen, text input button, these are actually Python objects. Some of them, such as login screen and root widgets are objects represented by classes which we created in the Python file, Login screen and the root widget. The other ones are classes you import from Kiv. So if we were to code in Python only, not in Kiv language, we would have to do something like from Kv dot UIXGridayout, import grid layout. So that is the same class as this one in here. But the KV file will import these objects implicitly. So it will import them either from your Python file, such as login screen and root widget or from the Kivi library. In this case, so we are not importing any grid layout here. Or the same thing would be with button. So from KV, UIX that button Import button. Same for text widget. So we are not importing these objects in here. So that's about the objects. All these are objects, and then you have these attributes of these objects. So if you open a Python shell and you import that grid layout object as I showed in here, and then you do the grid layout inside round brackets, you'll see that CLS is one of the attributes of the grid layout object. And so that's about the objects. Now, about the hierarchy of a KV app, it works like this. The highest in hierarchy is the app. So this app object in here. Then comes the screen manager, which is actually represented by the root widget. So the root widget comes after the app, and then we have the screen which is represented by login screen. So this login screen is just a child of screen. It behaves the same way as a screen. And by the way, we could also have done something else here, which I'm going to show you just now. You could simply pass login screen like that. And then here, what you could do is you could add the root Tidget which is in hierarchy, it's above the login screen. And then in the login screen, you could pass name login. Screen just like that. And you could delete that. So that would be the same code, and you get the same output, as you can see in here. So this indicates what I just said that root widget is a parent and then comes a login screen and inside login screen, you have grid layout, you have another grid layout, text input, and so on. However, to keep the code more organized, because here in the root widget, later on, we would have to add another screen like signup screen and so this would have its own children. And so then would have another screen like login error screen where the user would be sent if there was an error in the login credentials. So the code would become too complex. Therefore, what we have instead is, we have the login screen as a rule and also the root widget as a rule. And then we specify that the login screen is actually a child of the root widget using here. And so, likewise, we add other screens just the same way. So that's something to keep in mind because it helps you better understand how Kiwi works. And that's what I had about this video, and I hope to see you in the next video. 178. Creating a Bank Account Class: Well, in the previous lectures, I mentioned that I'll be creating a program and application where we'll be handling a sort of bank account so that we'll have a balance, and then we'll be applying some operations such as withdraw money from the bank account object and deposit money as well. I'll be storing the value so the balance in a simple text file. So that's not one of the ten programs we're building in the course. This is just to get you familiar with classes and to explain them a little bit more. So I'll do some housekeeping here. So let me create a folder here. And put all these existing files in this folder. So we have the previous files in here, and I'll create a new folder now. Let's call this account. And in this folder, I'll have my Python script. So let's call it like this. So under account, we have this Python file, and we also need this text file. We will be saving the current balance of our bank account. So this will be a trivial application because in real life, you don't want to save the bank account information, the balance in a text file. In real life, you want to save that in a real database, such as post gras well, for instance. But for the sake of practicing object or that programming, we will just save the balance value in this file. So this is our storage. And also for the sake of simplicity, we'll be working only on one single account. So our program will be able to process one account object because if you have multiple accounts, then the solution could be different from this. So you'd probably have to think about having a table and maybe a database would be necessary here. So let's think about our personal account. You could use this program for your personal notes, so you may want to keep track of your balance and you can use this Python program. And now the object here is the bank account. And this object, we should start thinking about what attributes this bank account object should have as an initial state. So we talked about this minimal object, and a bank account would have, of course, an initial balance. So let's start to create this account object and call it account. You can call it whatever you want, but I'll call it account. So in it is the first function we want to define and we pass self in there. An let's keep it like that for a moment. And we said our bank account object will have a balance attribute. And in our case, we have this balance dot TXT, and let's create an initial value there. Now, to create an object instance, we need to grab this value and pass it to our init function so that we construct this minimal object. Because we have a file, what we need to do is we need to read this number from this file. And naturally, what you'd want to pass here is some parameter like file path. So this is how I'm going to call that and now, if you remember, in the bookstore application in the backend script, here we also pass a parameter to the init function. And then we created a connection object out of this database file. In this particular case, what we want to create is an integer, so a number out of this file out of this file path. So you could do something like with open. So we're doing file handling with methods with open file path, and this is a text file, so we need to go with our mode, which means to read. So we're opening the file path, this file in read mode. As a file. So this is just a temporary variable that exists in this with a statement. And then we need to read from this file. So something like file dot RED. Yeah, that's it. This will read the file, but you're not storing that anywhere. So what you want to do is say self and balance equals to file dot Read. So what that will do it will save the value inside the text file in this instance variable. So this is an instance variable. That is how it's called. Actually, this is the instance variable and this is the object, so the account object. Good. This is almost good. And we also need to add the integer function there because this will be read as a string by default. So we need to convert that value to an integer. Yeah, that should work, and that should construct the object for us, the act object with a balance attached to it. And before going and creating the like withdraw method here and then deposit method. I'll prefer to call an instance of this class first. I'll do that here. Let's say sort that in the account variable. So this will be the object, the object that will be created out of this blueprint, the account blueprint, there you need to pass this argument, the argument for this parameter, which is balance TXT. Great. And for self Python will automatically pass the account object instance. Good. Now, this will create an object instance. And let me print out that object here. So we see some output in action. Python, and that's inside account folder and act pi. We got an error, no such file or directory for balance dot TXT. And the reason for that is that we need to pass the account directory there as well. So and this time, it's working. We had to pass the directory there because we are in this folder in the demo folder, and you need to pass the account folder first and then point to the balance of TXT. And this is the output. So it says main dot account object. So the account object of the main module. And what Min is is when you execute a script, like we did here, so you point to the script with Python, Python will assign this name to the module. So this module will get this name and the script, actually, but it's treated as a module. But if you import that module. So if I ran, I open an interactive shell now. So from the account folder, import. AC what happens is that you get the print function executed as well. But this time when you import file, so when you don't execute it like we did previously with Python account, AC that Pi, when you import the module, the module gets the name of script that it is written to. So in this case, it's AC without the extension. And here you also get the name of the package of the module. So packages are made of modules, and a package is like a folder, and there you have several modules or one module, like we have in this case. Our package here is account, so account, and then it has this module, and then this module has this class, the account class. So that was something I wanted to show you packages, modules, and classes. Great. Now, I'll exit this Python shell and play around with this script a little bit. And what we did here, we printed out the object name space, and we didn't get the actual balance as an output because we are not returning the balance here. But if you want to get the balance, you want to point to the balance, and that uses a dot notation to point to the object that holds the balance attribute. So let's see what we get this time. And yeah, 1,000. So that's the current balance. As you can see, you are able to access attributes of your object instance, using the dot notation. Good. Now let's add these other methods there. And what can we do to a bank account? Well, we can withdraw money. And you always need to pass self in all of your methods, and then the parameter that applies to that particular method. In this case, when you withdraw some money, well, you have an amount in mind that you want to withdraw. So you pass amount there as a parameter. No, just to be clear that you understand what I'm doing. What I'm doing here is I have an initial balance that is being read from this file, so this text file, and then I want to allow the user to apply operations, so withdraw money from this balance. And once the user executes the withdraw method, I want to update the balance number inside the object instance. And I don't want yet to write that balance to my balance file. So I just want to calculate something here like self balance equals to self balance. Well, this is a withdraw, so minus the amount that I want to withdraw. That means this will do self balance equals to 100 -100, let's say, and I'll end up with an updated balance of 900 in this case. That if I want, I can go ahead and open that file again here and then write this updated balance in that file. So that would be one solution. But a more constructive solution would probably be to have a specific method that commits the changes to the file. So you may want to withdraw some money and then you deposit some money inside the same session, and then you apply the commit method to save the changes. So this is the solution I want to go for. Yeah, we are done with withdraw method. Now deposit self and amount again. So this is a local variable. This is a local variable. They happen to have the same name, but they don't have to do much with each other. And self balance equals to self balance plus the amount in this case. Let's see what we have this for. And I'll keep this instance object here that is being generated. So we are insatiating an object instance, in other words, and print out the current balance. And then I want to withdraw some money. From my account object. That means I apply withdraw to the account object, and withdraw takes two arguments. So the object instance, which is passed automatically, and then the amount, which could be 100. And once I do that, I want to print out the updated balance. Let's see what it's going to do. Yeah, 1,000. So an object instance is created and you get 1,000 printed out because here you have 100, and then you take 100 out of that and so you end up with 900. Great. So if you run that again, you will notice that a new object instance is being created again. So you don't have 900 as a current balance anymore. You have 1,000. So that means you need to write the changes to the file if you want to save that balance. And we can do that using methods. Let's call it commit. And pass el there. And I don't think of any parameter that I need to pass through this commit method because all we will work with are the existing variables there. So this would be something like with open, well, we need to open the file path, but we have a small problem in here because a file path variable now is just a local variable in this init method. So if we pass it here, this function, this method, will not recognize it. So this is a bit different from the other the backend script that we wrote, because here we had this parameter like we do in here. But in this case, this parameter, it was only used inside the init method. So we didn't use it anywhere else. So there is a solution to that. One solution would be to go ahead and pass another let's call this path here. So another parameter to the commit method. Then when we call the commit method like we were doing with withdraw, we'd have to pass the balance dot TXT. Actually, this path to the commit method. While that would work, it's still not the best practice of object oriented paradigm. So we need to seek for another solution. And that would be to make this local variable and instance variable. And to do that, you'd do something like self and file path equals to file path. And what this does is so file path, don't confuse this with this. This happens to be the same, but you can also write another thing here, like anything. So this is the parameter of the unit function. So the balance that TXC will go to this parameter. So the path of this file will go to this parameter. And then you create this instance variable, and that instance variable will be equal to this path. But you can use this thing here. You can use it wherever you like inside your class. And in our case, we would like to use it in here. So we open the self file path in the right method this time because this time we need to write or to overwrite in more accurately to overwrite the current balance, which should be this one, for example. We want to override that to this file. So as file, this is just a temporary variable file and file dot write and self dot balance. Good, Let's try this. And we didn't get any update in the file here because I forgot to actually call the commit method. And so once we withdraw money, let's print that out in the console. And then account dot Commit without passing any argument explicitly because implicitly we're passing the object instance. Good. And we got an error there invalid literal for integer with base ten. So this would be the integer in line six. Here so the value that is being read by this method is not converting to an integer. And the reason is that this value has disappeared from balance that txty, and this is reading an empty string. So this is an empty string that is being read from this file, then you try to convert that and it doesn't work. Now, the reason that we got this empty string empty file here is when we got the previous error, so here we argument must be string, not integer. So what Python did was it opened the file with the method, but then it wasn't able to actually write a value inside that file. So the file ended up empty. So let me write the initial value there, and then now we should be able to run that again. And yeah, now we have the updated value. So again, what we did is we created the object instance, and then we printed in the current balance, which was read from this file, which was 1,000 at the beginning, and then we withdrew 1,000, so the balance was updated, and then we committed those changes to this file, so we get 900 there. Now, same thing if you want to add, let's say, 200 and deposit. Let's see if this will work. Uh, yeah, this was printed out. Let's check the file. Yeah. So this is our new balance. And yeah, I hope this clarifies a few concepts about object oriented programming. If you are creative, you can go ahead and expand this script, so you can add more methods there and maybe make this more of a real life application. So great. And this is about this lecture, and in the next lecture, I'll talk about inheritance, and we'll be expanding this script by applying inheritance in there. So talk to you in the next lecture. 179. Creating Classes Through Inheritance: Awesome. We're almost done with classes. But there's one last concept that I need you to know, and that is inheritance. Inheritance is the process of creating a new class out of a base class. So a new class that has all the properties and the methods of a base class, but also it has some other methods. So why do we do that? Well, I'll explain that to you through our example. So here we have this blueprint, so this class. And let me delete this not to confuse you. So there we were just calling the class instances. So we have this class which creates a bank account object for us. Then we can withdraw and deposit money from the bank account. Now, what if we want to transfer money from this bank account? So from our bank account, transfer money to another bank account. Well, we would have to add a transfer method in here. And then do something like just simple like self balance equal to self balance minus the amount. So we pass a transfer amount there, and that is substracted from our balance here. But as far as I know, you cannot transfer money from your saving account. You can transfer money from your checking account, but not from a saving account. So that method wouldn't make sense for a checking account. And this account is a general bank account. So what we could do is maybe we could create another class, like we could copy this and create another class and call it something else. And so we have all these methods there. So that's one solution. The other solution is to use inheritance. So here is where inheritance comes in handy. You derive a class out of a base class, which is a more general class like this account class in here. So let's create a new class. This new class is referred to as a subclass, and this will be the base class. So Again, you need to use the same syndax you use a class Q or there to create a class. Let's call this checking for checking account. The first thing we want to do is to create an innit method. With that init method, we will create like this minimal object that I have been talking about. Like in our base class, we also need here, we need a balance from our file, so we need that file path. But instead of writing this code again, as I said, what you can do is, well, first, you need to create an init function method, and, of course, pass self in there. You always pass the self parameter, whether that is base classes or a subclass. Then in this init method, you want to call the init method of your account class, which means that when you create an object instance of your checking class, this method will be executed when this method is executed, this method executes the init function of your account method so that you create this minimal object, which is the same as this one here, but then we will have some extra methods down here. So a checking account is this plus some other things. And here you need to pass self and the other parameter that is necessary for this init function. So here we are passing two parameters, and we should do the same in here. And if I execute this now, I'll get an error. So by intention, I want you to see what error we get. So let me create an instance of this function. So checking Oh, yeah, let's try that out. Um, here. Yep. That's inside the account folder, so here, and then dot pi. Let's see. So the first thing that this is saying is file path is not defined in line 21, which is this one here. And the reason for that is that we haven't defined any file path inside this function. So you can pass that inside the init brackets as a parameter. And then you need to pass that here as well. So let's say count balance dot TXT. Good. And we don't see any output there because we are not printing anything out. But what happened basically is that an object instance was created and this was called this method was called. And this class was initialized as well. Now, if we try to do so the whole point of inheritance is to do something like checking to access methods of the base class without writing those methods in your subclass. So let's say checking that deposit, and let's put an amount there. So ten. Now, if we execute that, we get this attribute error which says checking object has no attribute deposit, so this is not recognizing this method. And the reason to that is that we haven't yet satisfied the syntax of inheritance. And so the key here is to pass an argument to our checking subclass. And that argument is a base class, so the name of the base class. Say that if you do the same now and maybe print out the output to see what's happening, self dot balance. Sorry, I meant to say checking that balance. Sorry about that. And yeah, now it seems to be working. So this method was recognized, and what this did is from 1,100, which was the initial balance, it went up to 1,110. So this printed out the balance incess variable of the base class. So that's how we deposit some money in our checking account. Now, we want to transfer money, so we need to define a new method here, let's call this transfer. Transfer self there and also a local variable amount, so as a parameter. So this is just a local variable. It doesn't have to do with these once here. And then we want to update the balance. So we want to transfer some money to some account. That amount will be subtracted from our balance. So that means self balance equal to self balance minus amount. Now if we try New method there. So we are at this point. Let's transfer 110. Yeah. And I was expecting to have 1,100 here, but I got this number. And the reason to that is because we didn't commit the changes earlier when we deposited some money. So when we executed the script now, an object instance was created from the beginning and it got this number here, which wasn't updated to this because we didn't commit the changes earlier, but you get the idea. So from this balance, subtracting this one here, we get this. That means the transfer method is working, but we just need to apply the commit method there. Again, we can commit those changes. Yeah, let's see what we get now. So from 1,100, I want to transfer 100, and now I expect to have this updated to 1,000. Let's see. Yeah, 1,000 printed out here and 1,000 in here, too. So that is working great. Also, another thing I want you to know about the inheritance is that you can add your own instance variables for your subclass. Like, in this case, our only instance variable is balance, which has been inherited from the account base class. But we can add our own instance variables. So let's suppose this transfer also comes with some fee. So when you do a transfer, your bank charges you some money. And you want to give that fee as a parameter. So let's keep things simple and say, when you transfer money, so balance minus amount minus the fee. So let's not apply percentages there. Let's say, let's suppose we have a fee of $1 per transfer. Now, if we apply the transfer method again, we'll probably get an error because this fee is just a local variable here. So what you need to apply now is you need to transform this fee to an instance variable, which is self dot fee equals to fee. That means if you pass now a fee here, let's say, $1 or any other currency, and you pass it here, so this will go here, and that will go here, and this will be equal to the fee that you're passing here. And then we can make use of this instance variable and use it in this transfer method. Great. Now we are at 1,000 there, and let me execute this. Yeah. So 899, and they are the same here, which means 100 -100 minus the fee, you get this number. And yeah, I hope you're able to see how inheritance comes in handy to create subclasses out of base class. That's it for this lecture, and we have one more lecture to go. And in the next lecture, what I'll do is I'll clarify some terms of object oriented programming. So that will be a short lecture, and that will help you later on when you refer to documentation because there are quite a few concepts out there in OOP, and I don't want you to get confused with those. So I think that's an important lecture. Yeah, I'll talk to you later. 180. OOP Glossary +++: Hello again. And in this lecture, I would like to make sure you know the terminology of object oriented programming in Python. So now we have the class, which is this blueprint here, or you can call it a prototype that defines the characteristics of an object that is about to be created. So that's the class, and then we have the object instance or simply the object. So this year is an object. So a checking account object that stores data in this specific file path, and it has this attribute. So it has this fee. Then we have instance variables, and these are variables that are defined inside the methods of the class like fault path here. And these are accessible by the instance by the object instance that is created by that class. Then we also have something called class variable. So instance variable and class variables. Now, we didn't create a class variable in any of the previous lectures. So I'll go ahead and create one now. Let's create one for our checking account. So that would be something like let's say type equals two. Shaking. So a class variable is declared outside of the methods of that class, and class variables are shared by all the instances of class. So instance variables are shared by only the object instance. For instance, let me explain that. Here, these are one of our object instances, so we only have one object instance here, but we could have more. So I'll copy this and create another object instance here. And I'll call this let's say this is Jack's checking account. So I'll replace that and that that. And this is John's checking account. And they also have their personal storage there. So let's say Jack dot TXT and Joan dot TXT. So Jack has $100 and Joan has $200. Good. So we need to change that Jack Jack and Joan. And if we execute this script now, we will get two values printed out. So minus one for this statement here because Jack had so he had $100 there, but then he transferred 100 and then minus the fee of $1. And then he ended up with minus $1 there. He owns the bank some money. And then John had 200, so he has 99 now. So what I'm trying to say is that these variables belong only to their object. But if you try now, Jack's checking dot type. So you want to print that Print Jones checking dot type. You'll see that this class variable is shared by all the instances of that class. So what's the difference between class and instance variables. Class variables are rarely used so you'll really have to pass them in here. Another concept now doc strings. And a doc string is usually passed as soon as you write the clas key word, so just down the class keyword. That provides the explanation of your class. Let's say this class generates checking account objects. Then you close that with three quotes. So what that does is, you know, if we print that out, so we grab one of our object instances, let's say, Jo's checking dot. Double underscore, Doc, and double underscore again. So print that. So as you see, a doc string is used to provide some information about that class. So it's good to define the string when you're writing classes so that others, if they use your class, they can apply this operation here, they can see what the class is about. This is particularly useful when you're importing classes from modules. So when you don't actually see the code of your class, and you can do this and you have access to the doc string of the class. And then we have a concept of dota members, which actually is referred to class variables or instance variables. So this is a data member and this also is a data member as well. Then we have the constructor, which was this init function. And as you know, the init function, so the constructor constructs your class. Then you have class methods that you apply to your object instance. So transfer is a class method. So this is also a method, but it's a special method, so it's a constructor. And instantiation, if you hear about instantiation, that's a process of creating object instances. So instances of a class. Like this is instantiation of the class. And this one here as well. And, you know, inheritance now inheritance is when you create a subclass out of a base class. And this subclass shares the methods of the base class, plus it has its own methods that are specific to that subclass. Sometimes you also hear about attributes, and attributes are this one here. So when you access these instance variables or even class variables or even instance variables, you can say you're accessing attributes of your class instance, of your object. And yeah, that's about the vocabulary of object oriented programming in Python. And I really believe I have given you a solid understanding of object oriented programming and creating classes and objects and so on. If you still find something confusing, you can either re watch the videos because I know object oriented programming is a bit tricky, but you can even ask questions, and I'll make my best to explain things that are not yet clear to you. Yeah, I hope you find this useful. And I'll talk to you in the next lecture, so we're done with this section, and I'll see you later. 181. App 7: Mobile Feel-Good App Demo +: Hi, and welcome to a new section, of course. This section is quite special because here we are going to build a mobile app. So far, we have worked with desktop apps or web apps. But in this section, the app that we're going to build can run on Android and IOS devices, and it can also run on desktop devices. So we're going to build one single app with a graphical user interface, and users can use it on desktop, on Android and IOS. This app is going to have a login interface where the user can login and also sign up to register as users of the app. And then they can push some buttons to get some quotes. From the app. So they will say how they feel if they feel happy or sad or loved, so they will give a feeling. And the app will try to so if the user is sad, the app will try to make them happy by giving a quote that is relevant to their state of emotions. Right? So this is the app. I'm sure it's going to be interesting. We are going to use the KeV library. It is a third party library for Python, which allows you to build apps, so desktop and mobile apps also. Uh, so let's dive in and I'll talk to you in the next lecture. See you. 182. Creating a User Sign Up Page: Previously, we built this Python code and this Kiv code. So it's a Kiv app, which you execute by executing the Python code, not the Kiv code. So here, press the round button, and this is what we have. Let's admit it, it's a good looking interface, but it's rather cold for now because when we press these buttons, nothing happens. So let's go ahead and implement the sign up button. So what we want to do is when the user presses a sign up button, we want to change the page, the screen to another screen with another set of widgets. For that, we need to assign a function call to the sign up button. So let's go ahead and go to the QV code, locate the button sign up, which is in here. And so the button gets this attribute, the text attribute, but it can also get another attribute called on press on underscore press. What that attribute does is when the user presses the button, you are going to call the root dot sign up function. Don't forget the code parenthesis. So what is root and what is sign up? Root is a special name you can use inside a QV file, and root refers to the class of the rule widget. The rule widget in here where we are, is the login screen. So the class of login screen, which is login screen. So actually, root refers to the login screen class. And now we are using this dot notation. Then we're using the method of login screen. So sign up of Login screen where there is no sign up method, but we can create one. Define sign. Up, use the self parameter for class methods. And then let's do something simple for now. Let's just print out. Signup button press is just a string, which means it's going to be printed out on the terminal. Let's try this. Save the Kiwi file and run the Python file. And then press signup and as you can see in the terminal, signup button press string is printed out anytime I use the signup button. So it is as simple as that. Use attribute on press, and anytime the button is pressed, sign up will be called. This function. So now what we want to do for real is to switch the screen. But first, we need to create a screen. The way you create screens is in the Kiwi file. So we have the login screen here. Now we want to create, let's call this sign up screen. After the rule, you use the column, a tap to indent. And here is how this new screen will look like. So we have a label. We have two text input boxes, and we have a button. And everything is inside a grid layout. With one column. And this one column will simply have a level with text. Sign up for a space journey. Why not? Feel free to use your imagination, but make sure this is inside quotes. So it's a string. Then comes a text input. Et's use as hint text. The username string. So what is going to be shown in the textbox as a hint? Another text input with hint. Text. You guessed it. Password. And lastly, a button. With text, submit. Or you can write sign up whatever you like. So these are just strings. You can use whatever you like. So the idea is that when the user presses the submit button, the data, so the username and the password will be sent to the database where we are saving the user names and passwords. So this database will be readable, so we can write it. We can add more user names to this database, and it will also be readable, which means when a user tries to log in, we are going to read this database to see if the username and password the user is trying to send with a login button are or not in this database. And this database is going to be a JSON file, which is a simple way to handle user name and password data. Right. Now, if you save this Kiwi file and run the Python script, nothing is going to happen because the signup button is still printing out this symbol string, and the screen we just created is not being sent everywhere to be displayed. So we are not giving any orders to display the signup screen. So the next thing to do is to list sign up screen among the root widget widgets, so to say, name sign up. Screen. So screens have to have a name. And the reason for that is because in here now in the signup button, what we can do is the magic of doing self dot manager dot current equal to sign up screen. So signup screen is this string here that we have just created. Save the Kiwi file and run the Python file to see what's going on. So you may get this error from time to time KV factor factory exception, unknown class sign up screen, which means it's an error that occurred in your KV file. The class signup screen, which is this one here, it's unknown because there is no class KV in the Kiv library, such as it is for grid layout labels. These are all classes in the Kiwi library. So sign up screen is not a class in the KV Library, and it's not a class declared in the Python file. So what you need to do is just create a sign up screen class. Inheriting from screen and for now, just do pass, execute again, and sign up. And this is our new screen. So we got the label two text input boxes and one submit button, which doesn't do anything for now because this signup screen is connected to the class we just created the signup screen class. So whatever actions will be taken in this page, in this screen from the user, are going to correspond with some functions that we are going to add to the signup screen. And let me explain this line here, self dot manager dot current. So self is referring to the instance of this current class, of the class where self is. So login screen object. Login screen is the class, and self is the object that has been instantiated from this class that has been created from this class. And then manager manager is a property of screen. So since this class is inheriting from screen, so screen is a parent and login screen is a child. And the parent is giving the child all its methods, all its properties, all its attributes, including manager, of course. So self is able to access manager, and then manager has its own attribute which is current. So current of manager and manager of login screen. And this current attribute will get the name of a screen you want to switch to, which is sign up screen, this sign up screen in here, which is a widget we have created in here. And that's the idea. This is how you switch between screens using QV. Thanks. 183. Capturing User Input: Hi, again. What we have so far in our KV app is the first page of the app, which I chose to name it as login screen. So here is where the users login and sign up. And the login button has not been implemented, so is forgot password and sign up button works. Now, there's a few things what you might want to do next, such as, for example, you might want to do some design work to have some spaces between these buttons, these text inputs and this button, or maybe make these two buttons like smaller and just show them as links instead of buttons with squares. But you can do that, but what I prefer to do myself is first, I want to make a minimum design, which means I want to make the design work. I just want it's enough for me to see the buttons for now. I don't care if they are too big or too small. I want them to work. So I press a signup button, then I want to be able here to right? I use a name and password. And when I click Submit, I want to store this data in the database. So I want to create a new user with those data. And then at the end, after I have completed all the functionalities of the program, I want to play around with a design to make it better looking. So in this lecture, let's go ahead and implement the submit button so that these data are stored in a JSON file. Right, so let's locate the submit button which is in here and add the press attribute, which is going to execute the root dot. So the root is a sign up screen class. This one here. We're going to execute the method of that class. Let's call this method add user. Okay, so let's go ahead and add that function that method. Add user self let's pass for now. So this method is going to get the values, so the username and the password values, and send them and store them in Adjacent file. So where are the values? Well, we can access the username using root IDs, dot, and here we enter the ID of the widget where the username will be entered. So the text input widget. It doesn't have an ID, but we can give it an ID. ID. Username. I shouldn't be in quotes, so it's just a variable. Then here you will write username. Now, if you leave it like that, and also get root that IDs that password. So let's give an ID to password as well. ID column, password, just like that. And then in the ad user function, create some parameters. It can be using a password. So just like these Ds, but it's not related. You can have whatever parameter names as you like here. And for that reason, I would like to actually write Name P word, so not to be confused with these IDs. And for now, let me just print out U Name and P word, just to see what we have so far. Alright, sign up. Let's say u1p1, some username and password. Why not? Submit and if you don't get anything, maybe we didn't save the QB file. The Python file is saved automatically, and sign up again, U one, P one, submit. Yes, submit, submit. So what we are getting in return is this, which corresponds to Name, and this is P words. So these are the text input objects. Now, if you want the text that the user enters in these text input boxes, then you need to access the text property. Same for password, save, execute, and close this previous window to get the new one. One P one, submit, and now we get the actual text that the user entered. So that is how we get values from the text input boxes and send them to Python for further processing. So root refers to a sign up screen. Add user is a method in sign up screen. A root again is signup screen. Class IDs is a property of the signup screen object, which actually comes from the screen. So screen inherits it to sign up screen and signup screen has these IDs, which actually gives a sort of dictionary with all the IDs contained in the signup screen rule. So in this case, it gives you access to username to password. Root IDs that password, gives you text to the text input object that has an ID password, and then with text you access the actual value of that in the next lecture, let's go ahead and work with JSON File to store this data in the JSON file. 184. Processing User Sign Ups +: Hi, again, in this lecture, we are going to implement the sign up screen so that when the user enters the username and the password and then click Submit, these data are going to be stored in users JSON file, which I have it in here. So you can either create an empty file and call it like users dot JSON, or you can get my file, which you can find attached in the lecture resources. And in this file, I already have two users. These are JSON data. To make it look better, you can format it using if you're on Windows, use Shift Alt F. If you're on Mac, use Shift Option F. If you're on Linux, use Control Shift I. When you do that combination, what's going to happen is you're going to have the JSON code formatted like this. The idea here is that the app is going to add more users in here when the user presses that submit button in the signup page. This is basically a big Python dictionary. It starts here and it ends here. This dictionary has values like this key here. And the value of that first key, so that's the key of the big dictionary. The value of this key is this dictionary. So it's another dictionary inside the big dictionary, but that's another problem. It can happen like in this case. And so this dictionary has the data. So the username, it's again, user one like this. The password is passover one. So this is an existing user. I manually created this file, but the program will be able to also create this file and to add more users. And so here's where the value of this key ends and then starts the other key, the other user user two. That's username. You can also see here, passo two, and this is a date that this username was inserted in the JSON file. Let's keep this file open down here. Squeeze terminal space. And so the user presses the submit button, the submit button, calls the ad user function, and these two arguments are passed to the function call. So add user is this one in here. So you name P word. What are we going to do with these two values that the user entered in the text boxes? Well, what I'll do is, first of all, I open the users do Json file as file, and get the users load it in a dictionary, so users equal to json dot load. We need to input Jason here. So JSON is a library. And now, just as an intermediate step, let's print out the users to see what we've got so far. Sign up U one, P one, submit, and this is what we get. So that's what we currently have in the JSON file. And this is actually so users is a Python dictionary. Now, what we can do to this dictionary is we can add another value. So another pair of key and value, which is pretty easy to do. So, we say users. What key do we need to add? Well, we get that from Name. So we are going to add the U one username that I entered as a user. So we're going to have a third username there, and that will be its value is going to be a dictionary. So just like we have for user one, this dictionary, we are going to have for U one this dictionary as well, and so username. For Key, the username will be, again, U Name. And then password is going to be P word. P word. So we are here. P word, which is going to get the value P one. And then, since we don't have much more space here, I'm going to put a comma to continue the expression in a different line. If you feel a line is too long, you can split that line in multiple lines only if the line is inside parenthesis, such as in the case of a function definition or brackets, such as in the case of a list or braces, such as in the case of a dictionary. In all three cases, the code will work just fine. You cannot split a line that doesn't have parentheses, brackets or braces. If you try to do that, you're going to get a syntax error unless you use a BC slash. A backslash allows you to split an expression in multiple lines, even when that expression is not inside parentheses, brackets or braces. Splitting an expression into multiple lines makes for a more readable code. It is recommended to split an expression when it has reached 79 characters. However, this is just a recommendation. It doesn't have any effect in the code. So next, what is next? Well, created the key created. Value of that is going to be date time that now, let's import datetime first. From date, time, Import, date, time. So the daytime class of datetime module. So this is the datetime class that I inputed in here. Daytime dot now, I can show you what I'm trying to get here. So from date time, import, date, time, daytime dot now, we'll give you this datetime object. And what we want from that is we want to extract a string. We want to get the here, the month, the day, hours, minutes and seconds. So that is going to give us the date time in this string format. So this is going to go in here. Right. And that's it. Now let me print users again down here. Close this previous window, sign up U one, P one, submit. And you can see now that we have another pair of key and value. So the UO username with username UO password P one and create it at this very moment in time. So, what can we do with this new dictionary now? Well, nothing fancy. We just need to open users dot JSON, but this time in write mode as file, and we access JSON the JSON module, dump the user's dictionary to the file. And that's it. So what I'm doing at this point, I'm overwriting the users, the existing users that JSON file. So a completely new file is going to be created at this point, empty file. And in this empty file, I'm going to write the new users dictionary, which will be this one in here. So the new dictionary will include the existing users, as you saw in here, user one and user two, and it will also add the current user. So I hope that is clear. You know, if we test this now, interrupt the current session with Control C, execute the code, sign up, U one, P one, submit. So I press the submit button, nothing happens now because everything is happening on the background, so the user has the file has been updated. Now, if you look at the users that JSON file, you will see that there's currently a bug with Visual Studio code that it doesn't out to refresh the files when they are updated. I hope this will be solved soon by the Visual Studio code developers. This issue has been reported. But anyway, what we can do is you can go to the File Explorer in your operating system where you have these files and you can use an alternative text editor, such as Not Pat. I have atom here, text edit. So choose any of them, and you'll see that in the other editor, the changes have been recorded in the user's JSON file. So you can see that U one is there. So using a U one, pass or P one and the date it was created. That is how you add a new user to the JSON file. And lastly, what we need to add here because you see that when you press submit and nothing happens, you don't realize if you were successfully registered as user or not. So in the other lecture, let's create another screen that will show when the user presses a submit button. See you. 185. Creating a Sign Up Success Page: So at this point, we can add users to the database by writing them in these text boxes and pressing the submit button. Now, let's show another page when the user presses submit. Well, we can do that the same way we did when we switched from login screen to signup screen. So the way we did that was by writing in the sign up function of the login screen class, we wrote this self manager current equal to signup screen. We can do the same thing in here. So the ad user function is what is called when the user presses a submit button. So we can do self dot manager dot current equal to. Let's call this sign up screen success. So this is going to be another screen that we are going to list here, sign up. Screen success. The name of that should be the same as you used in there. And of course, we need to create that screen. Sign up screen success, a column. And what I'd like this page to look like is I'd like this page to have a label where it says, sign up successful. And then it should have a button under that label, which would say login page. So the user can press that button and go back to the login page where they can login. So to the login screen. Therefore, first of all, we need a grid layout. We just need one column, and then we need A label. The text of that would be. Sign up successful in codes, and then you need a button. The text of the button would be login page. And let's leave it like that for now. I'm just going to execute everything to see what we have this for. So we got an error factory exception. Of course, we don't have the sign up screen success. So we need to add a class sign up screen success, which inherits from screen, and let's do pass there. Execute again. Name screen's not defined. Yes, I made a type here, screen Sign up three P three, submit, sign up successful, the label and login page, which doesn't do anything for now because we don't have an press attribute for that button. So, yeah, to wrap it up, this is what we did to implement this screen to change to the next screen. So first, we added a self manager screen in the ad user function. That will change the current screen to this screen in here. And this screen has been defined in here, and it's represented by this class in Python. And that's it. So 12, three, and four points, we had to add. Now, try as an exercise to implement the login button. So when the user presses the login button in the page, you want to sign up, four Pi four. When the user presses login, go back to the main page, so to the login page, which is this one in here. Try to do that. 186. Switching Between Pages: So let me quickly implement the login page button. Right. The login page button is just here. So on press root dot, go to Login. That's how I call the function. And so we are in the signup screen success rule, which means we need to go to the signup screen success class and define go to login function self and of course, self, that's manager, that's current, equal to the login screen, which is this one in here. So we already have that screen. We don't have to create a new screen now. Save the QV file and execute, sign up. Ux, P six, it doesn't matter what user name and password you submit. Sign up successful that's labeled login page, and it takes you back to the login screen. Now, something to keep in mind is the direction of the transition of the screens. So currently, by default, the transition is called left. So you go sign up. So the movement is that the next screen is going towards the left. So you eight pH. Now the next screen will go towards the left like that. And when you go to login, maybe you'd want to go to the right. So to change the transition to the right, which makes more sense. So if you want to do that, go to where you are setting the current screen. And so we want to change the transition of the login screen. So when we set the current screen as login, we want that manager transition that direction is right. Execute that, sign up. I'm just going to submit some empty strings there just to be quick with this trying out of the interface. So submit that's a new user with empty strings. It doesn't matter. You can put some restrictions later if you like. So go to login page. And so this time, the next screen is coming from the left towards the right. So if that is what you want, which I think it makes some sense, then you need to use this transition property of the manager property, which has a direction property and set it to right. That's the idea. 187. Processing User Login Credentials: What we did so far with our program is we build the first page where the user can login and we also build the signup page where new users can sign up and be a member in our JSON database. In this lecture, we're going to implement the login functionality. Let me show you how the finished version of the program works. I'm not showing you the code. Not yet, just how the login will work. Ignore the nice looking interface, or now we will do that later. Now we have to think about the functionality. So when the user logs in, they enter the data. They press login, and they go to this internal page of the program. So here then we have a button, which if we hover the mouse, it will become red, and if we click, it will log us out and it will take us back to the login page. If the Delta are wrong, it will say wrong username or password. So again, when the data are correct, it will take us to this page. So in this lecture, let's go ahead and build this screen. I made a screenshot of that, so we have it here for reference. So we need to add one more screen in the list of screens here. Let's name the screen, Login screen success. And name let's be on the same lines, Login screen Success then create a rule for that screen. I'm just going to copy and paste it. And so what do we have here? Well, we start with the grid layout, which has one column. For now, I'm just going to provide a simple button. Later on, we will implement the functionality that you just show with that animation. When you put your mouse over the button, the button will become red. So for now, let's just use a simple button. With text. Look out on press. So we're going to have to create a login screen success class in the Python code and create a function there to log out the user. So look out. Yeah, that's how I would like to call the function in the login screen success class that we are going to create. Let's leave the button like that, and then we have a label. How do you feel that is the label? Text So we are asking the user how they feel so they can enter a feeling, and then we give them some quotes, depending on how they feel to make them feel better or to enhance their feeling. Quotes are a good thing. Very smart people have thought well about them, so let's use them. Let's make use of them. Text input. With hint? Text. So here you can write whatever you like, but I'd like to give them a hint to let them know what they can enter here. So without having to include any big description here in the body of the interface of the page, let's keep the interface clean, and we make use of this area here in the textbook. So things to try. Happy, sad, unloved. Yeah, that should be okay. And then we have another button with text Enlighten me. Feel free to use any name. That's how far my imagination goes. And now, on press, what are we going to do when the user presses that button? Well, when the user presses that button, we are going to display some text below the button. So therefore, we'll need a label. And it's text for now is just an empty string. So let's include an press attribute for the button later on. For now, let me go ahead and write a class login screen success, which inherits, of course, from screen and it has a method. Lo out. Lo out to log the user out. And here I would like to first, define a direction for the transition of this screen. Let's put it right. The logout is going back to the previous page, it makes sense to have a right direction for the transition. Then of course, manager, that's current equal to. Where do we want to take the user after the logout? We want to take the user to the login screen. Again, that makes some sense, right? So login screen. All right, so we have the page. We constructed the login login screen success page, which was this one in here. So let me close this to have more room for the code. However, we haven't yet implemented the functionality of the login button. So u1p1 login doesn't work. So let's locate the login button. Which is in the login screen. Yes. The login screen screen. Yes. So that's a button button login. So what do we want to do on an on press event. Well, we want to execute a route that log login function, which we need to have in the login screen class just here. So it's basically the same idea as ads user. A function where we gave the ad user function, we provided it with the username and the password. So again, we do the same thing with define login. Self and so here we need to give two arguments. The first one would be roots, that IDs, that username, that text. And the second would be root IDs dot password dot text. So we are talking here, sorry about the type of here. We're talking about the user name that the user enters in the text input box and the password that the user enters in the text input box in the login screen. So root refers to the login screen to the current rule where you are writing the code here. And we don't have an ID for text input, so let's go ahead and do ID, use the name, same for password. And so then we take this username and password in the login function. Let's use Name and P word as parameters. You can use whatever name you like. You could also use username and password. So how do we log in a user? Well, the idea is that we need to open to read the JSON file where we have the user's data and check to see if that username and password are in that file. Or more accurately, if that username is in the file and it has a password, the password that the user is providing in the graphical user interface. If that is the case, then we switch the screen using a manager dot current property. We switch the screen to the screen that I just showed you that we just built and that we haven't seen yet how it looks like. So let me quickly implement this with open users dot JSON has file. So in read mode, when we don't define the R like that, that implicitly means that we are reading the file. Users equal to JSON that load. The file. So that will give us a dictionary. Users will be the dictionary containing all the data in the users that JSON file. And then if you name in users. So what we are doing here is, let me show you. So we need this JSON library and Users will be the dictionary, right. Lots of data there. And if we say, for example, if 77 in users, we are going to get through because U seven is actually among the dictionary keys. So here, U seven, you can ignore the user. They are just a prefix to denote that these are Unicode data, but these are the strings inside the codes. So U seven is among the dictionary keys. You can also get a clear list of the keys. With that. So users that kiss, you see that us seven is among those data. So that is why we get true, and we can make use of that and say, I username in users, so first we check if the username is in the database. But we also need to check and users, you name Password equal to PWord so that is our condition, actually. So the first is that the user name has to exist. And the second is that you know, the users, you name, let's say, seven, so users U seven is equivalent of this. So that will give us the dictionary that the key u seven has. This is like the value that the ku seven has. So it's a dictionary. And if we continue our accessing chain, we do password. So we are accessing the value of key password. Each of these dictionaries have this password as a key, and the value of that password is the actual password. So P seven in this case. So we are checking if the password of that user is a password that the user is providing here. So password that text goes in here. This has to be equal, not an assignment operator. So if that is the case, then south manager that current equal to the login success page, login screen success which we created. Right. And we also need to add an s conditional there, but let me try to see what we have so far and debug the code if we have some problems. So seven P seven login, and here is a screen. So this is a button Logout. How do you feel? The textbox we created Enlighten me, and this is the area where the text would be displayed. For now, it doesn't work because we haven't attached a function to the Enlighten me button. Let me now try the Logout button. So out is not defined, as you can see here the error. So our logout button which is here on press, it's pointing to actually we should write root, that's Logout. So it's pointing to the login screen success Logout function. So that was a problem. We didn't specify the class that had this out button. So let me try again. P seven login, Lou and we are back to the login page when we do logout. And if we enter some wrong data, nothing will happen. So here is what we are going to do. We're going to add a label just under the login button between these two buttons and the login button. So let's go ahead and do that. We are talking about the login screen. That is the login button. So let's add the label with text, it's empty for now. So save that close that window, run again. Now we have a space here. So that's a label. And in that label now, when the data are correct, we are going to the Login screen success page s. So now we need to get access to the ID of the label. So let's first put an ID to the label, login wrong. So here, now we need to access that label. The way you do that is using self. Self points to the login screen object. Then we look for the IDs of self. Login, wrong ID. So that is the label object. Now we need to access the text of the label object and assign the text wrong username or password. So make sure you save the QV file and run the code. Just some random data which are not in the database, Login and we get the label there as we expected. Seven P seven, login, and we go to the login page. So that is how you access elements from the Ki file. So when you are in the KivFle, root will point to the associated class of that rule. So login screen, login screen class, these names have to be the same. And when you are in the Python file, self is pointing to that class login screen class. And since login screen here and login screen there communicate to each other, they get and receive data. That means the self object knows about the IDs and all the widgets that the login screen contains. So therefore, you look for the login wrong ID to give you label this object of the login screen, and then you access text. So selfie roots there, and that's it. Let's go in the next lecture now and make some more cool things about the interface. Thank 188. Displaying Output to the User +: For this lecture, I'd like you to go to the resources of this lecture and download the three text files. Then in the Explorer here in your IDE, create a new folder. Give it a name such as quotes, and then put those three files in that des folder. You can use drag and drop if you like. For example, I have these files somewhere, and I'm going to just drag and drop them in this folder. So you see that now the files are in the quotes folder. So what we are going to do in this lecture is in the program that we have we are going to write one of these three supported fillings for now. You can add more files later if you have some data. But this is what we have so far. And so when the user presses the Enlighten me button, we want to show one of the quotes that are inside the happy TXT file. So one of these lines. Some are long, some are shorter. And so if the user enters SAD, then you want to display here in this area one of the lines of the SAD, that TxD file. Those are also our quotes. And so you get the idea. And if the user enters an unknown filling, such as, let's say, excited. And when they press a button, you want to show try another filling because you cannot have all possible fillings there covered. So this is what we are going to do in this lecture. Main dot pi. So let's start from the button. Try to locate the Enlighten me button. Or at least that's how my button is called. So button that button is part of the login screen success page. And we don't have an press attribute yet. So on press, what you want to do is you want to execute a method of the login screen success class, which I have it right here. So that login screen success, it already has a method, Logout, which is executed when this button is pressed the Logout button. Now we want to implement the Gute method. Code self as usual. And so this method now has to communicate the value that the user entered in the text input. So which is root that IDs dot. We don't have an ID for text input, so let's put an ID. So this is a text input where the user entered the filling. And so let's put filling there. IDs that filling, we want to get the text of that text input. So that filling will go here. Let's just call it fill, not to be confused with the filling word. And the first thing we might want to do is, let's see if we are accessing the filling text correctly. So print fill. And make sure you save the design that KV file execute Login. I was able to login because I have this username I created earlier. When I signed up, I created one username which is an empty string and an empty string for the password. So basically, it's a user with empty string, empty string as user name and password, which works because I haven't put any restrictions on the username and password. So this is just for simplicity when you try when you test the application. Happy enlighten me, and so we get the happy. String there. And if that is with a big ge, you're going to get happy. The first thing we might want to do is to change the field into lowercase. Even if the user enters happy with a capital age, we are going to convert that to all lowercase so that we can compare now with the names in the text files with the file names. Let's now see what available feelings we have. So I'm assigning a variable available feelings, and I'm going to use the globe module to get a list of file names. This is what this is going to give me. An error, of course, because I didn't import glob. So it gives you a list with all the files. This is available all the available fillings. We are here in the get quote method. Now, the available fillings list now looks like a list of file paths. What I want to do is I want to extract all the names of these files, only the set part. A way to do that is by using the path object of the Path leap library, you don't have to install this library. It comes with Python. It's standard library. Using Path, if you give path a path, such as codes, set TXT and then extract the STEM out of that. I will give you the name of the file without the extension without the other part of the path. In fact, you have many methods of path, and STEM is one of them. So you can get the suffix, the name of the file, including the extension such as that and so on. And so what we can do here now is we need to make use of that STEM property, and we need to apply that to all the filenames. To do that, so you can use a least comprehension. So available feelings equal to path. Let's say filename for filename in available feelings. And here I'd like to split the line into multiple lines. Since this is inside square brackets, I'm allowed to split the line. And so we want the stem out of that. Then we might want to try a print in here of available fillings. Also make sure to import from path lip Import Path and then execute the app And I got an error when I pressed the button. String object has no attribute STEM. Yeah, of course, because I did here. Instead of putting STEM after the path object, I put it just next to the file name. Filename is string. So that's why you get STR has no STEM. So let's put it in here and try again. Enlighten me. So happy set and Loaf. That's what we want. Now we have the available feelings in a list. What can I do now? I can say I feel in available feelings. So if that feeling is in the available feelings, then what we want to do next is we want to open that file that has that feeling that has a quote for that feeling. So let's use an open. I'm going to use string formatting here. F. So quotes, I'm going to open this file path, which has this fill dot TXT a file. So what am I doing here? Well, that thing, what that is going to give me is, let's say the feel that the user entered was happy, right? So we get that variable. It has a value. And if we get now this string, going to give us is the file path for that filling. So this expression here in these braces is going to be replaced with the value of that variable of the field variable. So I hope that is clear. And then we want to get all the des, all that file using the read lines method. So that will give us a list of all the codes. So let me unindent and print the codes to see what we've got this for. Happy, the quotes were happy, and this is a list. So as I told you, happiness is when you what you think and what you say, and so on. And then it was told by Mahatma Gandhi, and then you have a comma, and there is where the other quote starts. And so one, we have a list of multiple strings, each string representing a quote. So what can we do with this quote now? Hmm. What we can do is we can get the self that ideas that. The idea of this label where we want to show the quote, which is just under the enlightened me button. So the idea, quote, quote. Quote, that text. So the text of that label will be a random choice of the quotes list. So what does this method do is It gets a list as input. So one, two, three, and it returns a random item out of that list anytime you execute it. So just pure random. So therefore, we're going to get one of these strings, one of these quotes, and that quote is going to be set as a text of the label. So that's how it works. And let's make sure we import random. And we are ready to execute the app. A login happy Enlighten me. And we got this error which is quite common attributes error. Super has no attribute get attribute. This happens when the Python file doesn't find that ID, the quote ID in this case. So you can see that the error happened in line 61. So that line in there is not working well. That is, I think, because I didn't save the QV file when I entered when I updated the ID of the label here. So I wrote an ID but I didn't save the QV file. So let me try again. I'm happy these errors emerge because you learn how to fix them. Enlighten me. And yeah, so we get the label displayed in here. When you press again, that random that choice function is going to get another random choice out of the list. Sometimes I suppose it may display the same quote, which is fine, I think, but there are ways to make it display a different quote from the previous one, but this is working quite good, I think. Expect of the case when there is a long quote, and it's out of the borders of the app window. So this is a problem, but nothing to worry about because we are going to implement a scroll view later on, which will squeeze this label, and it will make it flexible. By resizing the label depending on the widget on the app size. For now, let me close that and finish the Ils block, self that ID code, that text equals to try another filling. So let me try one more time, and we are done with this video. So that is working. That is also working. And I feel pretty. Oh, try another filling. We don't support that. And this is how we make an app. That picks a quote randomly. So the functionality of the program is pretty much done. What's left to do is we need to make it a bit pretty the interface and the buttons and the spaces between the buttons and add some animation. So these are things that will help you to make some real world apps, which are modern and nice to use from the users and which you can actually sell. So let's do that in the next lectures. 189. Stylizing the Login Page: Now that the app functionality is working fine, we will start with the styling. So all the buttons are doing what they are supposed to do. Well, except of the forgot password button, which is supposed to be as an exercise for you to solve. So now in the next video, what we are going to do is we are going to work on the styling. So this is a program we built together this f, and this is the end stylized product. So in this video in this very video, we are going to work on the login screen. In fact, you can resize them like that to see exactly how they will look in a real phone because that's more or less the size of a phone, the size ratio. So let's close these two interfaces, and I'll keep this interface open in here to use it as a reference. So we are not doing any work in the Python file here in the KV file. That's about the design. Right, so first thing you want to add is some padding and some spacing in this grid layout. 15, I'll explain what that means, of course, spacing 2020. So this grid layout, what it is, is we have the main grid layout, which is the entire widget, and then this grid layout has the user login, label these two text inputs and this button. And also an invisible label in here. So we want to add some padding, which means 15 horizontally, which means the distance of the grid layout of this grid layout to the outside borders of the app. So you see we have some 15 distance here, and also there is some distance which you cannot see, but there is a padding here vertically between this label and the main frame. So that is padding, the outside space of this grid layout. And then spacing is 2020 means spacing between the widgets of these grid layouts. So spacing is an internal thing, and padding is external. You can think of it like that. So 20 pixels between these two and 20 in here as well, between this textbox and this button. Well, you can see that there's more space actually than 20 pixels between the button and this text input. But that is because we have also applied in this interface in this end product. I've also applied some sizing to the button itself. So there is a padding plus the reduction in size of the button. That's why you see more space here. So let's keep it like this safe. And then you need to execute the Python file as always. And so now we have some padding and some spacing between these widgets. How about increasing the font size of user login this label? So you need to go to the label and set the font size to 20. It has to be a string like this SP. So now the phone size is bigger. Now, let's work on the size of the login button. You see that this looks a bit too wide. So how about making it a bit shorter? Well, in QV, there is an attribute called size hint, which you can give to a widget, for example, to a button here. Size hint. Now, the way QV works is that by default, the area is proportionally divided between the widget, which means that, for example, here we have the main grid layout which takes the entire space because it's one grid layout. So it's like a single child, it will get everything. Then this grid layout has two children. It has this grid layout here and it has this grid layout in here. And the area between these two children will be equally divided. And so this grid layout, the second one has two buttons, the forgot password button and the signup button. Therefore, you can see that this grid layout here has half of the main grid layout. And the other grid layout, which is the first grid layout, has the other half. The same happens for the children of each of these two grid layouts. So the children of the first grid layout. The label and the text inputs, each of them will again get assigned the space they deserve. So here we had one label, two, three, four, and an invisible label, so five widgets, and so every widget we have 20% of this space. However, there is a size hint attribute which I just introduced to you, which allows you to change how much a widget gets from its parent, so size hint. So let's give a value of 0.3 and 0.5. To the login button. What's going to happen is that the login button will be squeezed vertically. You see, because we gave a value of 0.5. So it has half the height. And we also gave a value of 0.3 to squeeze it horizontally, but that doesn't work because there are no other widgets here on the side. So either way, the login button will get, again, the entire space. It's not splitting any space with other widgets in this direction in the horizontal direction. To be able to change the button, what we need to do actually is to indent this button and make it the child of a relative layout widget. If you save that and execute, now you'll see that the button has changed position. I actually has a 0.3, 30% of this horizontal space, as you can see, it's one third. Of this horizontal space, and also 0.5, 50% of the height. But if you make this 0.5 less than that, if you make it 0.1, for example, you're not going to get a button with a very, very small height because there's a label there which has a fixed size. And so the minimum you can get is the height of the label for the button. Now, how can we put this button in the center? We need to use a pause hint, which gets a dictionary. Center X 0.5. And center Y 0.6. I experimented with some different values, and this is what I found to be best. However, not yet because these guys here, these buttons are taking too much space. So what we can do is we go to the grid layout that has those buttons. This one here, and we say size. Hint, 0.20 0.2. Save that and see what happens. Hm. So it's looking much better so size hint is quite magical because it allows you to make the sizes relative. You don't want to set a fixed size because there are different sizes in mobile devices, and it's better to keep everything relatively sized. So what I just did here is I gave this grid layout a 20% space. So 20% here, and this here is 80% for the other grid layout. So the button was squeezing because it tried to do its best using these values that I gave in here for the button, this login button, but it couldn't do it because this grid layout was taking too much space. Therefore, 20% is good. And if you like now, you can give some padding of ten and ten and spacing of ten and zero. This was the old one. This is a new one. So not bad. I just gave some spacing between the buttons and some padding relative to the outside. So the horizontal space, this one, and the vertical spacing vertical. And there are no other buttons vertical on top of this, so this doesn't make much sense. So zero is just fine. And let me close that. And lastly, let's make those two buttons look like links. So these are the forgot password and sign up. Let's change the background color, which is currently gray to an RGB and opacity format. So Alpha for opacity, and it takes a value 0-1. So it decimal values. You can put 0.1 and so on. I'll put one, one, one, and zero. Zero means the background color is completely transparent. I'll save that and execute. You can see now that forgot password is like that. However, when I click the button, it doesn't seem to be doing anything like the sign up button. So what we can do is Play around with the opacity of the text. Let's put it a value of one if self state is normal, se 0.5. So that's a nice magic that I'll explain to you how it works. You see, you know, when I click the button, I understand that I'm clicking the button. So what's happening is that the opacity is one. If the state of self self refers to the current widget which is button. So remember root referred to the rule, which would be like login screen in here. But self referred to this very button. And if you want to access a property of the grid layout, you could do parent like that. So that self that parent would be pointing to the parent of button, which is grid layout. But we don't need that right now, so so otherwise, if the state is not normal, this is the normal state of button is not pressed. There are other states like pressed released, but this state is normal. And otherwise, if the state is not normal, such as this state here, I've pressed the button. In that case, we want to give a value of 0.5 to opacity. So this entire thing here is Python code. Everything actually on the right side of these attributes here, here, there. Everything there is Python code. And lastly, let's change the color of the bottom. You can use a color attribute for that. Let's do 0.1. So that means 10% of red, 70% of green, and 100% of blue with a transparency of one, so not transparent. Save that. And I'm going to copy these three attributes and give them to the other button as well, to the signup button, save the file, execute. And yeah, this is what I meant to do. So sign up for a password. I press it. I go to the other page, to the signup page. So again, this is the interface we have this far for the logins One last thing I'd like to add is that currently, when we enter a username, the password is visible. We want to show stars instead of that. So go to the text input for the password and access the password attribute and set it to true. So when you set that attribute to true, What happens is that the text input is treated as password input, so it doesn't show the password. And thanks for following this video, and we'll go and stylize the other pages of the app in the next videos. See you. 190. Stylizing the Sign Up Page: Hi. What you are looking at is the sign up page. Here on this side is the program we have built so far, and this is how this program should look like after this video. So let's go ahead and add some padding and some spacing to our sign up page. This is a code. So we're talking about the sign up screen. I think a padding of 2020 and a spacing of 2020 again, should be fine. So let me execute sign up. And so I think that is fine, but if you like, you can play around with this padding and spacing and maybe with the other size hint attributes that I showed you earlier. So to give sients to the grid layout to this one and then other si hints to the text input boxes, it's up to you. I think this is looking good anyway, for a mobile screen size. 191. Making the Buttons Interactive: Hi, I'm very excited to show you now how to stylize the main page of the app, which is the page where the user will spend most of the time. So the page where they get to these quotes. And here on the left is what we have this far how our main page looks like. So that is the login screen success page. That's how we called it. And this how the page will look like after this couple of videos. So first, what we're going to do is first, we are going to add some padding and some spacing to have these buttons separated from each other. So that's the first thing. Then the second thing is we are going to make this big button look like this fancy button here, which changes color when we hover the mouse, when we place the mouse on top of the button. And then we are also going to add some scrolling to this label area here so that the entire text is shown in a small area, and the user is able to scroll and see the entire text. So let's go ahead and work on some padding and spacing, and then on the bottom. Before we begin, I'd like you to go to the resources and download the hoverbl dot py file, the Logout, hover dot PNG file, and the Logout not hover dot PNG file. I'll explain in just a bit what they are. So the padding now, login screen success Hmm. Let's add the padding of 30, 30 and spacing of 30, 30, as well. See what we get. Oh, yeah, it looks better. So now the button, the Kiv library does not natively have an object to implement hover behaviors so that something changes when you hover the mouse, or there's not an easy way to do so. But someone developed a very small submodule called hoverbl and you can get that file and put it in the same directory with your main dot py file. So they are in the same folder. And then what you do is you don't have to change the hoverbltPi file, so I'm just going to close it. And then what we can do is we import from hoverbl, we import the hover behavior object. So that is a class, the class hover behavior inside the hoverbel dot py file. So that's what we're going to use. And the way we are going to use that is, let's go down here. And I'm going to create a class and call it image button. So this will be a special button. It's not going to be a simple button anymore, but it's going to be an image button. And this image button is going to inherit from the hover behavior class and a couple of other classes as well, which I'm going to import in here. So the way we are going to implement this button is by having two different images. I created these images in Power Points. You can easily create them. You have these symbols. And you add some text and then make the background transparent. And so you have one blue and one red. So the two different states you want the button to have, it's a PNG image. And so the idea is that this button will not have text. I will have an image. Therefore, we need to import from qv dot x dot image, import, image. And lastly, from qv dot UX behaviors import. Button behavior, and that's it. Now we get image and button behavior, and we place them as parents of the image button. Object. And all we need to do here is just pass. It's just a class that gets together these three objects. To make a class, so the image button class that has attributes that behaves like these three objects. So what we do then is we go to the image button, and I place this wrong here. Sorry. So this should be here, actually, image button. We are talking about the logout button, not the enlighten me button. And we don't need that logout text anymore. So we don't need this logout text because we are using our own image which has the text inside. So remove that on press root Lookout. Yes, that's correct. And source of this image button, it's going to be Logout Hover I self dot Hovert Lookout, No, hover. Oh, dot PNG, of course. So that is the path of the image. So Overt, this self hovert what it is, is this attribute of the Hort behavior class. So it's a bowling property. It could be either true or false. So this is Python code. I told you that everything on the right of this attributes is Python code. So we are going to set a source the logout hover image for this image button. If this is true if hovered is true. So the hoverlPiFle is detecting if a mouse is over that button. Otherwise, we put logout not hover. So that path there. So let me see what's happening. Yeah, so it's working fine as easy as that. But the button is obviously taking too much space in here. So it's basically taking one, two, three, four, five, 20%, so we have five widgets. Each of them is getting 20% of the space. And so let's do some size hinting then. Size hint. I think a good amount would be like 0.35, 0.35. So let's see. Yeah, I think this is good. And now this is in the center. So if you want to put it on the right, you want to change the position. And again, there's the position hint attribute, which gets a dictionary, center X. I think a good number would be 0.93 and center Y. 0.8. Now, if we try this, see what we have, nothing will happen. Because the button when we use this position hinting, the widget has to be inside another widget called relative layout. If you save the Kiwi file now and execute the file, that will do the magic. If I press the button, it will not work. And the reason why that doesn't work is hidden here in how we order these patterns of this image button class. The bottom behavior should be the first one because that order may hide the methods of that bottom behavior. Now, let me try again Look out. So now it works. Log in again. And this is about this image button implementation. And in the next lecture, let's go ahead and implement this scroll view here of the label. See here. 192. Creating a Scrollable Area: Hi, so let's keep working on the main page of our app. And so the user enters some codes. And as you know, this label here, the display it's not optimized. So what we need to do is, as you see, we need to wrap the text inside the borders of the app so that if the device where the app is running is like that, the text will show normally as it shows right now. But the mobile, if the device is mobile phone, it will look like this. And so you want to wrap the text inside this area here so that the user can see the entire quote. So we are in the login screen success page, and we're talking about the text size attribute. So let's change the text size to self dot width and self dot height. What is self dot width and what is self dot height? Self dot width, self refers to the current widget. So self is actually the label, and width is width of the label height is the height of the label. So the text will get the width and the height of the label where it resides, which means, let me save the Kiwi file. So every widget here has a size. And so label is one of five widgets. Label, you have button, you have text input, label, and you have this relative layout, and the label is taking 20% here. It's invisible, but if it had a background like this button, it would look like the text input size and this button size. So it's somewhere in here. So that's the width, and that's the height, more or less of the label. So if I say SD, let's try to get a long quote. So this is what we get now. So it's looking better. If we squeeze, you see the text is wrapping inside the label height and label width. So you can see that now when I squeeze the window, I resize it, the label is dynamically resized, and so is the button and the text input. And so the text size will also reflect the size of the label, as you can see in here. But this is not yet enough. So how about giving the text more area to stretch vertically? If you want to do that, you want to set the text size height to none. So you don't want it to be related to the label. So if you save that, try the code. You see now the height of the text is greater than the height of the label. The label is somewhere here. So let me resize it again. So the label height is this high, so it's somewhere here, and the text height is greater than the label height. This is better. We can see the text, but obviously the text is overlying. It's on top of other widgets, so that's not ideal yet, of course. So what can we do here? Well, what I'm thinking is, we need to find a way to change the height of the label to match the height of the text. So in this case, that would be like having more of this black area here of the label. So having the label up to here and having the other widgets squeezed above the label. So let's change the height of the label to fit the height of the text. How can we do that? Well, first of all, we need the label Y. So the height of the label, we need that to ignore the size hinting, which means, let me show you what that means. Let me try another quote. So what that means is that the label height, it's not anymore 20% of the grid layout, but it has a fixed size of 100 pixels by default. So by default, the height of the label now is 100 pixels. And so that's the same as height 100. If I run this now, we're going to get the same exact output. But if you change this to 400, so the height of the label, this is the height attribute of the label, not of the text. So if you see now, the label is quite bigger. Let's say set. So now that takes has a lot of space. So you squeeze it and you can see the text. But this is not what we want. We said we want the height to be dynamic. We want the height to be reflecting the height of the text so that when we have the window stretched like this, we want these buttons to be down here, and we want the label to be smaller. So the way to do that is instead of having a fixed size for the height, we want to self that texture size. And we get the second element of that text orcise tuple. So text or size is a tuple which contains two items. The first item is the width of the text. So it's a dynamic value. It's going to change when you resize the window. And so the first value is the width and the second is the height. So with this index, we access the second element of the topple. If we wanted the first element, we would use zero here. We want the second, which is the height. So save that So, you see, now, the label is dynamic, so it's changing its size depending on the size of the text. And we can see the entire text. And when we stretch the window like that, we don't have any excessive blank area here, which would be the label body. However, this is not ideal, of course, and there's one more thing left what we can do here. What we need to do is to have some space for the scroll view widget. And the label, together with its attributes, I have to indent it with tab to have it as a child of the scroll view. So scroll view now is at the same level with the other widget, button text input, the other label, and so on. So save that Kivfle now, execute. Happy. And so you can see a scroller there. Sad. Enlighten me. So it's working with every kind of text. When the text is short, there is no scrolling, and when the text is longer, there is a scrolling automatically. So you can go to the end of the text. And so that is how you build a scroll view, which has a label and the label has some text inside. I hope you enjoyed it, and I'll see you in the next video. 193. Preparing the Environment to Deploy the Mobile App: Higen. In the next videos, I'm very happy to show you how to make an APK file out of the Python file that we already have that we already built in the previous lectures. Now, an APK file is a file that can be installed in Android phone so that the app is usable on mobile. Currently, we only have a dot py file. So we have the main dot py file and the design dot KV file. And we also have a bunch of extra files such as this OverltpYfle and these PNG files as well, and the database, which is stored in the user's dot Json file. So all these files will be bundled in one APK file. In order to make an APK file, we need to use a library called Bildozer. It's a Python library which we can install with. PIP or Conda. The problem is that making APK files on Windows or Mac operating systems, it's very hard, not to say impossible. The best thing we can do is to use a Linux operating system such as Ubuntu. But I'm not going to ask you to wipe out your Windows operating system or your MacOS and install a Linux on your computer. Now, we are going to use a Virtual machine, which is a software that you can install on MacOS or Windows. And inside that software, that software will behave like a computer. But it's a virtual computer. It's a software. So inside that software, you can install operating systems such as Linux, Windows or Mac. So in this lecture, I'm going to show you how to install Virtual Box. Thistallation is easy whether you are on Windows or MacOS. So just go to virtualbox.org. And click on the Download button, then click one in one of the links. So if you are on Windows, it means that the host operating system is Windows. So Windows will host the Ubuntu Linux system. I'm currently on a Windows machine, so I'm going to click on Windows Hosts. So that will give me the executable file of Virtual Box. Once the file download. Go ahead and double click to install. I don't want a shortcut on desktop or on the quick launch bar, but feel free to leave those options as checked. Yes, we need Internet in that virtual box in that virtual machine, virtual computer. So install. I would go for Install again. Finish and Oracle Virtual Box will launch now, expect it to take a while, and here it is. So the interface is quite simple. We have some buttons here. We are interested in the new button. But first, before I do that, you need to go to ubuntu.com. And download an Ubuntu operating system. So go to the Download button, go to Ubuntu desktop. There are two versions now, but this is a stable version, the one with green button. So I'm going to download that. Expect this to take a while because it's around 2 gigabytes. Yeah, that's quite a lot of data. Once you download that file, go again to Oracle Virtual Box and go to New. Given name, I'm going to call it Ubuntu and you'll see that these drop down lists are automatically updated. So you want to select Linux here. We are installing a Linux operating system and Ubuntu 64 bit. That's at least what I downloaded from ubunto.com, but your system will automatically detect the architecture of the program. So I'm going to click next now, the memory size, they say that the recommended size is one gigabytes for RAM, but I would say you should go for higher, which is at least 4 gigabytes. If you don't have much RAM on your computer on your physical computer, maybe you should go for less and see how Ubuntu will work with that much memory. But this is the idea. This is 3,000 megabytes is the RAM size on this Windows computer that I'm using, and I'm giving 4 megabytes to the virtual Linux computer. So that would be the maximum size 4 gigabytes of RAM for Linux. Click on Next. Create a virtual hard disk now. Create. You want a VDI, so click next. Dynamically allocated is fine. This again is up to you. I recommend 20 gigabytes if you have them. So around 20 gigabytes, but give it at least ten, or if you don't have much space in your hard disk in your computer, then you should opt for less like 5 gigabytes and see how things work. Normally, if you run out of space or out of RAM, you should get some pop up windows from a virtual box telling you that the space is not enough, but the more space, the better. Click on Create. And so now we have created a layer here. You want to go to start And this will ask you to select a startup disk. So you want to go to this folder here and then locate the ISO file that you downloaded from ubuntu.com. So that's one there. Click on Start. Now, this window here is kind of small but you can go to machine and settings, go to display. And here in the scale factor, you might want to increase this to 300%. Click on Okay. And now you see the screen is a bit bigger. So this is the next screen that we got. You want to go to Install Ubuntu. It go for English here and English there for the keyboard layout. These settings are fine. Then you want to select as disk and install Buntu that will simply delete all your programs, your photos, and your computer, everything you have you ever had. I'm just kidding. This is only about the programs you have inside the Virtual box, which we don't have any. So this would be the case if you were overwriting an existing operating system that you already had inside this virtual box. So it has nothing to do with your programs in your main operating system, which would be Windows or MacOS. So just go to Install Now. Continue. Select your time zone. Select a name for the computer. I'll just go for login automatically without providing a password, however you need to choose a password. Click Continue. And so that will take a while now until the files are installed. So until Ubuntu is installed in this virtual machine in this virtual box software. My installation was completed and the prompt is asking me to restart, so I'm going to click on Restart now. That will restart the Linux operating system, not the host operating system, which is Windows in my case. So just restarting Ubuntu inside virtual box. There seems to be an error, and I just pressed Enter and things seems to be working. So this is Ubuntu. If you want to see the startup guide. Just click on next. And done. Now, you might want to go to Oracle Virtual Box, so the Virtual Box interface and then go to machine and settings and then go to General Advanced. And you might want to enable the shared clipboard and dragon drop options. I set them as bidirectional, which means that you can copy files from your host's operating system, so from Windows or Mac to Linux to Ubuntu and vice versa. However, I've noticed that this doesn't work. If you get this prompt, it means that there are some updates for Ubuntu. But I'm just going to close this window. So I'll assume that the option of copy pasting files between the systems doesn't work. That's why I'm going to show you what you can do to get files from your host operating system to your Linux to your Ubuntu operating system. So this is the folder where I have all the files that I need for this APK file for the mobile version of the program. So it's everything we went through plus this Kv Build Dozer installer dot SH file. This is a file that you can download from the resources, and I'm going to show you what that file is for. But for now, I'm just going to use Dropbox. So I have the project files already in my Dropbox on Windows. So the folder is this one here. Teaching has all the files. All right, so I'm going to right click and copy Dropbox link. So this is on Windows. It's not on Linux. It's outside Virtual box. Another way to do this would be to use this service, gofle dot IO. That allows you to upload a file, and that will give you a link. And so that link you can use you can put that link inside Linux because there is a browser there. You have Firefox inside Linux. But since we cannot copy and paste, we're going to have to manually type that link. So in my case, I'm going to use Drawbox and I'm going to usebtle.com to shorten the URL that I created. So that's URL there. And enter that URL in the browser of your Linux operating system. If you don't want to go through this file sharing, you can just use this URL to get my files so you can download the files directly from your Linux system using the browser. Go to more direct Download. Save File. Okay. The files should have now been downloaded and you can find them in the files. Download. Right, click on the downloaded Zip file. Go to extract two. You want to select the desktop. But click on this new folder icon there, to create a folder. Let's say Project one, create and select. So now we see this project one folder here, and there is the teaching folder inside, and these are the files. And so let's end this video here. This was how to install Visual box and how to set up Linux inside the Virtual box and how to get the files inside that Linux operating system. So now we are ready to create a mobile executable file that will run on Android. So let's do that in the next video. 194. Creating an APK file for Android: Hello again. In the previous video, what I showed you was how to install Virtual Box, how to install Ubuntu inside Virtual Box, and then we transported the project files into this Ubuntu operating system. Now they are in the file system inside Ubuntu. What we're going to do now is we are going to use the Bill Dozer Python library to create an APK file. But before we do that, we need to install some dependencies in the Ubuntu operating system because Bulldoser needs them to be able to create this APK mobile file. To do that, while you are in the folder where the project files are, right click and go to open to terminal. So that will open the Linux terminal. You'll see this current directory. So that is where your files are. If you do LS, you'll see that these are the files. So main dot pi is there. Make sure this is named exactly main dot pi because Bill Dozer needs to see that file. And that file should have the main program. I don't need this screenshot file, so I'm just going to remove that as you can see, the screenshot file is not there anymore. To locate the open windows on Ubuntu, go to activities, and you'll see that the terminal is open and the file explorer is also open as well. Click on terminal. That will bring back the terminal window. Now, among those files, you see this Kiv Bulldozer installer dot sH. You can see the content of that file using CAT and write the name of file. So this is what that file has inside. Basically, these are instructions on installing many dependencies, including Python, Belser, and Kiwi, because this Linux system doesn't have Kiwi either. So go down here. We are again here, click Bash, key press tab to auto complete the name. So that is the name of the SH file. Click Enter. Enter the password for your Ubuntu system. This is a password that you created when you were installing Ubuntu. Ubuntu asked you for a username and a password and expect this to take a while. Ubuntu is now downloading these packages from the Internet and the Internet was automatically enabled when you install Ubuntu, so I didn't have to do any manual configuration of the Internet connection. Sometimes you'll get some warnings, but you can ignore them. This is not a stable process because there's a lot of dependencies involved and sometimes you'll get some errors when we create that APK file so that file will not be created sometimes. It's not an easy process, but you can read the errors, what they are saying and maybe search on Google to see what others are talking about about that particular error. There's no guarantee that it will work. That being said, Linux is the best operating system to be able to create these APK packages. Finally, the installation has finished my computer in my virtual Linux computer. The next step is optional. You might want to try out the app that you have. To do that, use Python, Python three command, Minda's Pi, which is the file that we have been using. The app is working fine with Python. Let's try it out. Yeah, it's working fine. So close that window. And the next thing we want to do is to create a Bull Dozer specification file. To do that, we use Bull Dozer, so the command Bull Dozer in it. Okay, that created this Bilozer dot spec file. You can minimize this window and find that file in the file system. You can ignore this file. We don't need this. It was just some notes I was using. So bulloser dot spec, you can double click it and it will open with the text editor app. So here, what we have here is we can change some parameters of the app that we are going to create. Let's put the title, how do you feel? You can choose a name for the package, but don't use spaces there. I'll just leave it my app. And you want to stop here, what extensions do you want the package to include? So we have Pi files. We have some PNG files as well, and we also have JSON files. So this is what we want to be included. KV file as well, but it's already there. So KV is already there, and then go further down. So this is going to be version 0.1. It's our first deployment, and then you want to stop in here. So what requirement does your package have? Well, let's see what libraries. What third party libraries do we have in our main pi file? So we have the QV file. Hoerbl is a local file. It's not a third party library. This local file is included in the project file, so you don't have to declare that in the requirements, and that's all we have. JSON and Globe are standard Python libraries, so they come with Python random as well, and also Path leap. So in the Builders Dot Spec file, we don't have to add anything else other than Python three and KV. Go down here, you want to enable all orientations, not only portraits on the mobile. That's fine. And this version here should be changed to eight. And that's all. Make sure to save the file, click Save or Control S, close, then go back to the terminal window. And now what's left to do is we want to run the command that will create, hopefully, the APK file. That is, build Saucer Android, debug, At some point that we'll ask you if you want to accept the license to accept the license, press Y and then enter. That initially failed in my system. So if that is the case, you might want to go back and look at the error because these are just generic messages. You want to locate after these colors, you want to locate here the top of red message. That command failed. I think that is because we specified version eight. Let's try to go to the Blows or spec file and change that delete that value and replace it with arm 64 V eTA, paste that in there. And besides this, we also forgot, I think we forgot to add the dot TXT extension among the accepted extensions here. Dot TXT because dot TXT is the file where we have those quotes. So make sure to save this, close it, and go to the terminal again. This time, we're going to try again to build the APK file using Bulldozer Android. But this time we're going to add the clean flag. And then debug. So the clean flag will make sure not to mess with the previous efforts of trying to build the APK package. Presenter, again, we're going to have to wait a while for the process of packaging to be completed. But this time, you're not going to be asked to accept the license, and the process might be quicker than before. So let's wait a bit. So the second built efforts were completed in my Linux, go to the folder. Ben has been created the folder. So inside that, you should be able to find APK file. That's about this video. In the next video, I'm going to get an Android device, and I'm going to show you how to install that APK file on Android device. See you. 195. Installing the APK file on Android: So the next step is to get this APK file, put it on an Android device, and install it so we can play with the app on the actual mobile device. Now, you can be creative here how to transfer this file to your mobile device. It would be easier if this Linux system was installed in your physical computer, not in a virtual box. So in real life, if you want to take things seriously making mobile apps with Python, you may want to actually install Ubuntu in your computer to have a Linux computer. You could do this with dual boot, if you have a Windows laptop or PC, and in that case, you could connect your mobile phone with a USB cable so you could easily place the files in your mobile device. In this case, I want to have a general solution that works for everyone. So I'm going to upload this file into this go file dot IO service. So click there and go to Bin. That is the file. Upload. And now you can get that link here, the download link, and you can put this in on the browser of your mobile device. Hi. So let me show you now how to install the APG file on an Android Device. So that is go file dot IO web page where I uploaded the APK file so that I could share it on my mobile device. That is one of the ways. So my browser is pointing to that service. I'm going to go to download. Press the download button. So it says downloading. When the APK file downloads, it will ask you if you want to install it. And so press on Install. Android is prompting you if you want to install this app or not because normally you don't want to install apps that you don't know where they came from for security reasons. So this app, we build this app, so we want to go to Install anyway. I got the message app installed. If you want to send the app for scanning to Google, I don't want to do that. So don't send. So press Done and go ahead and locate the app. So here is the app. I'm going to click it. It's loading. And two U one, P one, login. Happy. Click on Enlighten me and you see the messages are displaying. So it's working. I hope this works well for you. I hope you enjoy the process. If the Build was not successful on your case, please look at the frequently asked questions to see if your question is answered there, and you can try to do the build process again with the Bildoser Android. Always use the clean option, and so I'll see you in the next videos. 196. Web Scraping with Python & Beautiful Soup: Hi, and welcome to this interesting section. You're going to learn web scraping with Python in this section. In this lecture, I wanted to explain what web scraping means. So web scraping means scrapping the web for information, or in other words, extracting information from web pages. Let's say you want to extract information about real estate. Maybe you want to know the price trend over time and place. And I don't think there exists some nice Excel files with well structured data that you can go ahead and download and do data analysis on that right away. In reality, such data are spread over HML web pages of real estate websites. In our example. So you're going to have to scrap them and put them in a structured in a well structured format such as Excel and Excel file, CSV, Pandas DataFrames or other tabular formats. And putting that in a well structured format is referred to as web scrapping, and Python is excellent in that. Specifically, we're going to use a Python library named Beautiful Soup. So in this section, I'll introduce you to Beautiful Soup, and we're going to extract some information from a simple web page while I show you how beautiful soup works. Then in the next section, so once we consume the lectures of this section, we'll go ahead and extract some real estate information such as property addresses and property price, the area, and other features of properties. We're going to extract that information from a big real estate website. So, yeah, that's about what scraping is. Yeah, I'll talk to you in the next lecture. 197. How Web Scraping Works +: So how does web scrapping work anyway? How is Python able to grab the information from a webpage and store it as text so that you can analyze it in your convenience? Well, this text that you see here. So this is an example website, and actually this domain is reserved for examples. But it's a normal webpage built with HTML and CSS and other web development tools. So HTML is what renders the elements, the text and everything. On the browser. Now, luckily, you can see the code of every web page by going to view page source as I did here. So this is the code, the HTML code, as you see it, it opens here with HML tags, and it closes here. And so this has title of the webpage, which is this one here, example domain, and so on. And most importantly, for you to know is the SML script is made of SDML elements. So this line here is an SML element, so it's a meta element, and then we have division elements, which is this one here. We have paragraph elements this year. And these are called tags. So the Div tag and the division closing tag. So opening division tag, division tag. And then we have the body tag. So here is where the visible part of the HML page of the webpage is placed. So everything you place inside the body tags, you will see there. So if you have example, domain here, this domain is established to be used, et cetera, here is where you see that text. This domain is established to be used for, et cetera. And so the HTML elements are key for web scrabbing. So basically, what you do is that, let's say you want to extract the text of age one tags out of all the DIF all the divisions. So what you tell Python to do is you tell Python to go to all the age one tags and extract the text of this tags. Python will do that. But first of all, though, you need to load this entire script in Python, and the way to do that is by using the request library. So requests allows you to give Python URL, so like example.com, and Python will grab all the texts. Then once you have this text, you'll use the beautiful soap library to extract all the elements from the text. So for instance, the exam, the text inside HD h one tags. And then you can store the extracted text in variables in Python dictionaries or Pandas data frames, and wherever you find it useful for your needs. So that's the concept and you can see the same source code, as you might already know, from the inspect. So right click Inspect and you see this. So here is like this source code, but you see it more organized. So for instance, if you're hovering your mouse over the body tags, the corresponding element in the webpage will be highlighted as you see it. So if you expand this, now you are on the edge on tags and so on. So this allows you to actually see the names of the tax for the elements you want to extract. So we will use the inspect window for understanding the source code of our webpages. So that's about the concept of web scrapping. And I'll see you in the next lecture, where I'll load a webpage in Python, and then we will extract some simple data from the webpage. So just to get you started with request library and the beautiful soap library as well. So let's move on. 198. Web Scraping Example with Python: So as you see, it's quite a simple one. And intentionally, I tried to find a simple web page for you. So here we go. I didn't want to distract you with lots of content for now. Later, you'll be able to grab information from a big website with lots of data. So for now let's try to grab. Let's say we want to extract the names of the cities from this page. So if you want to follow MIP, please type in this address on your address bar with dot HTML at the end. And so we've got only three cities here that we will be extracting. But the code that we will write will work with any number of rows here. I'll be using the iPython notebook or the Jupiter notebook as it is called now, so it was renamed to JPEter Notebook. So right shift right, click and open your command line. JPter Node Book. And I'll create a Python free e book. Great. So the first thing you want to do is you want to load this source code in Python. The way to do that is by using the request library. So if you don't have that installed, you can just go ahead and install it with PIP install or requests just like that. I have it already, so already satisfied. But the process is very easy, so you already know how to install packages with PIP. And you also need the beautiful soup library. So to install that, you need to say PIP install again and not beautiful soup, but Bs for so it stands for beautiful soap four. So that's the latest version of beautiful soap. And then. So you want to import requests, and so the first thing you want to do is load the source code. And then we start looking for HDML tags and extracting elements from those tags. But let me import beautiful soap as well. So from BC BC four, import. Beautiful soup. So that's the syntax. You're importing the beautiful soup class from BC four. If you are on Python two, this should be slightly different. So you want to import beautiful soap directly like this. Okay, Alt Enter and go to the next line. So to load a web page. It's good to create a variable, so you can load the webpage source code to this variable. So equal to requests dot Get so the G method. So you point to the library and then to the Get method. And all you need to pass here is the URL of the web page that you want to load. So in this case, pythonhw.com. Example dot HTML. So don't forget the HTML. This is just a static web page, so you should pass the ICML there. Now, this should create a request object. So we're still not there. And what you want to do is grab the content from this request data type and maybe store it in another variable. So the content stored in a C variable like that. And if you want to check now, what this sees, you'll see that this is a byte data type. And you can print it if you want. Even though this doesn't look very nice, this is actually the source code that you see in here. So we have the head tag and the HTML tags and everything else there. And now, here is where the beautiful soup comes into play. So all the request does is it loads the source code of the web page, but in a very scrambled form as you see here. Now, if you want to make this beautiful and extract the elements and the text and everything out of this source code, you want to use beautiful soap. So all beautiful soup does is parsing this source code and giving you what you want. So giving you the elements of the HTML text you're interested about. So you have already loaded this content, and now what you want to do is maybe create a variable and call it soup. And that would be equal to the beautiful soup and guess what you want to pass here. Well, that would be the content. And maybe another argument. So you want to specify the parser you want to use for parsing this data. That is normally the HDML parser. So this is what you want to use almost always. If you don't specify this, you'll get a warning, but still things will work. So I normally pass it there. And once you've done that, so execute that L. If you know, print soup prettify with empty brackets there. You'll see the source code of the web page in an organized form. So beautiful soap is trained to actually recognize these tags and then render them in a visual way for the human eye. However, this is just for demonstration. Normally, you'll not have to actually use the pretty phi method a lot because a better method to see this code, as I already mentioned before, is to let me delete the cell. We don't need that. So a better way to see that source code is to go to your web page and go to inspect and here you see a better syntax of the HML code. So here you'll see that. We have three divisions here. With a cities class. We have some more divisions here, but this is what we're interested about. So the body is everything. And if you expand one of these divisions, you'll see that we have an H two tag, so a heading tag, and also a paragraph tag. So P tag and H two tags. And also the other division, which is this one here, has this H two tag and the paragraph tag. And Tokyo also has the same thing. So our duty now is to extract the names of these elements. So that would be the H two, the text of the H two tags inside the city's tags. So naturally, you start thinking about iterating through these boxes which are actually divisions. So you want to go through here, here and here and extract what you want to extract. So we go back to the code, and what you want to do is perform a method called find A. And what you want to find is Divs Devs, but there may be lots of divs in the webpage. So, for instance, we have two more divs here. And we don't want these to be found. We only want these three. But these three, as you see, they have a common class attribute which is equal to cities. So we want to make use of that. And we pass here a dictionary, which would be class equals to cities. Okay, let me create a variable here, call it all and execute it. Now, if you print all you'll see that the divisions have been extracted from the source code. So from the soup, which was the entire source code. And I'd like you to actually see closely here. You can see that the first division is divided by comma here. And then the second division starts. So for Paris, Paris is the second and it ends here and then Tokyo starts here. So we've got a list with three elements, one for each division. Now, if you want to find only the first element with this class attribute, self cities, you'd want to use the find method. And so in this case, you don't get a list, but you get the code division for the first division only, which happens to be A tag element of beautiful soup. So it's not a plain string, but it's a special, let's say, a special beautiful soap string. So that beautiful soap knows its structure, so it knows what elements or where the tags are and where the text is and so on. So that beautiful soup is able to give you the information that you are looking for. So again, so you extract the first element. Now, an alternative way to extract the first element is logically, so we have all elements here is to use list indexing. So this object that I just showed you, the tech object of beautiful soup supports indexing. So you execute that. And in this case, as you see, you extract the first item of the tag object, or you could do it like this, so you grab all of them. So here you have all of them, and zero is the first one. You get the idea. Okay, but what if you want only the H to tags from this D class? Well, in that case, what you'd want to do is refer to the object and then apply the fine method again. And this time, you'd want to get the H two element. And in this case, you don't have a class attribute, so you'll have to leave it like that. And you get an error because what I did here is I didn't point to this division, but I pointed to actually the list. Containing all these divisions. Python is trying to get the H two, but this result set method doesn't have this H two element. So what you want to do is you want to point to the first element of the list, and that gives you the H two element with the text and the text, which is like a list, so you want to perform a zero indexing there. And if you want London only, you apply text and you get London. So this is what we wanted, right? To extract the cities. So we extracted London. Now, how about extracting Paris and Tokyo? Well, as you might guess, we need to use four loop. But first, let me summarize what we did here. So we loaded the content up here, which is this one here, and then we loaded this content in the beautiful soup method. And beautiful soup makes this soup beautiful so that it recognizes the tags. And so what we did then is we found, we extracted from this content. We extracted all the division elements. So together with the tags and the attributes and the text inside them. Everything inside these divisions with a class equals to cities. Then we can perform for each of these elements of this list, we can perform, again, a find all method. So we can find sub tax of this division tags. And in this case, we found the H tag. And then we grab the first item of the list, which in this case happened to be a list with only one item. So each of these divisions have one H to tax. Or alternatively, you could just use find here and without using this indexing. But this is a general method. Then we apply the text attribute there so to extract the text out of this element. So we got London. Now, we need to do the same, but in this case, by iterating. So for, let's say item in O, you want to print out. So item here is this one here. So this would be the first item. So you want to print out the item that find pull. And you want to find the H two tags from this first item, for example. So H two tags, and then you need to apply this zero index in there, and you want to grab the text from this, and that's it. Here are the data. Alternatively, you could just pass P here and you get the paragraphs. So this one's here, the text. So that's the idea of loading web pages in Python and parsing them with beautiful soap and extracting texts out of the webpage. So sorry if I was a bit repetitive in explaining this stuff, but I really want to make sure you understand the core concepts. On the other hand, if you found this very basic I would say, let's move on to the next lectures where we'll be extracting some information from a more advanced website, and we'll be extracting links and not only text. So that's a real world program and a very interesting one. So I'll talk to you later. 199. App 8: Web Scrapping App Demo ++: Hey, welcome to this new section. And, as usual here in the first lecture, I'll just give you a demonstration of the program that you'll be building. And, so you will have this program on your hands by the end of this section. And yeah, during my work as a freelancer, I've seen an increase in demand for getting data from the Internet from various clients, and these data can serve for different purposes. For instance, you may need property data from real estate websites such as this one here, or you may need businesses, so list of businesses, and you may want to look for that on yellow pages or even information from Wikipedia. The problem is these websites they don't give you like a CSV with the data that you're looking for. So they don't do that. And what you want to do in that case is you want to scrap data from these websites. And yeah, you may need data for different purposes. And we can do that. We can do web scrapping. So the process is called Webscrapping. We can do that with Python. So Python is perfect for that. Basically, what you do is you get these data and you store them in a table, such as a Pampas data frame here, and you can also export that easily in output. Yeah, in this section, what you're going to do is you're going to do web scrapping on this real estate website. So with Python, you're going to perform a search query on a certain location. So Python will search for data, and then it will get those data, and it will store them in this table and then lastly, I will say then in an out food CSV file. So everything is automatic. And you may want to get different attributes from the website. So in our case, we got this set of attributes. And yeah, you can get those data in a single round of program. But of course, first of all, you need to build that program, and that's what we're going to do in the next lectures. So this is very useful. And in addition to learning web scrapping, this will also boost your Python skills in general. And yeah, let's kick this off, and I'll talk to you in the next lecture. 200. Loading the Webpage in Python: There, I'm glad if you're watching this, it's great that you have made it this far in the course. And in this lecture, actually, throughout the next few lectures, you learn how to scrap data from this website. So this is a real estate website, and what it does, it lists properties for sale or for rent. So basically, let's say rock springs. There are actually a few rock springs there, so let's say Wyoming Rock Springs in Wyoming. So we are looking for some properties there. A in Wyoming and it says it found 28 listings. So it's quite a small city, small town. So the idea is that you learn how to scrap data of each of these properties. So which can be priced is you have the address there and the number of bets that the property has and baths and so on. And you also get the square feet of the properties. If that is available. So properties don't have that so we have to count for that, too. And also, you scrap data from multiple pages. So we have ten properties here in this first page. And then in the next page, we have ten other, and then in the third last page, we have the rest, which should be eight, so 28 in total. No, normally, I assume that you know about the requests and the beautiful soap libraries. So you should have taken the previous lectures where we scraped data from a simple web page, so that was a trivial example. And I believe after that example, you end up with that, now what? So, for that reason, I'd want you to learn how to scrap some real data. So this is one of the real programs that we are building in this course. And in the script that we are about to write, you'll face some real programming issues there, which is very important to build up your skills, your Python skills. Just one issue. Before scrapping data from a website, it's good to read the data policies of that website. So they may have some policies against using or getting their data. I'm using this for educational purposes, so I believe you'll be doing the same. So that shouldn't be a problem. So let's go ahead and write it program. And I'll be using the Jupiter Notebook. I suggest you do the same. So this will create a Jupiter notebook file. So I'm using Python three. Call this Century 21. Great. So you now know that the very first thing you want to do when writing a program, maybe Import the libraries that you'll be using. So you'll be using requests and beautiful soap. So from By four Import. Great. Now, go to the next line. And let's go back to the website. So now, the first thing you may want to think about is, how do we load the source code of the web pages? And now, actually, this is a bit complicated. I mean, not much complicated, but it's different from the static web page that we scrapped in the previous lectures. So here we have we are going to be scrapping three pages, as I said, and the good thing is that every one of these pages has a unique URL. So so when you are in the main page here, you see the URL is just plain simple. But then when you search place, so look at the URL now when I search, the URL will change. So it went to real estate Rock Springs and Wyoming. So this is the string, so for the place that you search, Rock Springs and WY and you also got something else here that you need to be aware of. So the idea is that now you get this URL. So first, we'll be scrapping the first page only. And once we grab that, then we think about the next pages. So because the next pages are the same, so the structure is the same, but we'll just be writing a loop to iterate through the next pages. So let's go ahead and unload the first page. Let's say request dot get here's the URL. And we want the content of this request object. So that content. And let's print it out. So a simple test there. Mm hmm. Mm hmm. All right, so my Internet connection is working. That's all we know about this code because we can't read it. So what we want to do is go to the next sale and make that code more readable. So we need to use the beautiful suplibrar here. C and the parser, which is HTML Parser. And maybe printout soup. B pretty five. Well, let's see. So this is the page. Sometimes you may get kicked out of the web page, so you may want to make sure that the page has loaded correctly. So maybe I could go here and search for something. So Winchester, I'll search for Winchester. Yeah, so the page seems to have loaded correctly. And we don't need the prettify there. So let me clean the notebook there. So we were able to load the page correctly with requests. And now what is next? Well, next is we need to understand the structure of the webpage. So we need to use inspect tool in our browser, and we'll do that in the next lecture. So see. 201. Extracting Div Elements: Great. So let's go to our page. So we have searched for work springs there. And what we want to do now is to understand the structure of the webpage. So we use Inspect tool there. And the logic is that you want to iterate through all of these boxes, so to say. So we grab the HTML of these boxes, and then we go inside of those HTMLs. So we iterate through those HTMLs. And then we find the tags for the data that we want to get. So that brings us to the point that we should be looking for the elements that identify these boxes. So if I go inspect here again, I'll see that this half box has this div with this ID. And actually, I want an upper level, so I want the entire box there. So if I go here, now, this looks like the entire box here. So the inside here should be the data. This is the picture. And this is the price. So, here is a text for the price, and we have this prop price as a class for the H four tag, which creates this number here. So this is the first div division. And then we should have the next div somewhere there, here. So property row, property row here, property row, property row again. So the class property row and again here. And let me put this down here. So docking it at the bottom so that we can see the entire box there. Okay, like this. So here we go. So what I would like to scrap and save them in a CSV file or Excel file with pandas later is I'm going to get the price, the address, the number of beds, the number of baths, the area of the property, and also the lot size if there is a lot. So some properties don't have a load there. So we have a trick there, and you're going to learn how to crack that. And so these are the data that I'm going to grab from each property. And let me put this up here again. And you can either click here and inspect, so it goes directly to the elements, so to the price or go manually, which is probably better because it helps you understand better the website, the structure of the webpage. So this is a price, and then down here, here inside here should be the address elements, primary details. These are the bets. So if we expand this, you'll see that here is the text for the address. So it has a span of with this class name. And this here is the name of the town and the code for the state and the ZIP code as well. Great. But first of all, as I said, I need to go through this property row class of the Div. So let's do that here. And you know that you have a method called final, which applies to the soup object. So final, and this will generate a list with all the dif elements that have a class of was it Property row? Yeah, it's property row. Property row with capital R, that's it. So I'll enter, execute that. And so what can you do? Well, all print it out and maybe see what you get. So it starts at the very beginning of the very first property row division. So that would be the first price, which was this one here up here, here. Then there should be a comma here after the first division ends. But anyway, if you don't want to find them manually, you can do something. You can find the length of this all object which is like a list, it's not exactly a list. Actually, it's it's a result set element of the B four of the beautiful soup library, but it has a length function just like list two. So length, and you get ten. And we have exactly ten results for each page. So first page here, second page ten results and so on. Now, this is like a list, so it doesn't have a fine method, but it's elements. So let's say the first element, this element has a final method. So just like you do with beautiful soup, so you apply the method, a final method, a beautiful soup to find tags elements, you can do the same for the elements of the A list. So to say, let's call the result set a list. And so that means you can apply a fine method to this source code. So let's look for the price. Well, you can go to the inspect or just look through here if that is, this is not much code. So I found the price here. So we have the H four tags, H four. And it also has a property price a price class. So let's pass that. You can choose not to pass that. But the problem you may run into if you don't pass the class name is that if you have other H four tags in the code, Python will extract them as well. So you need to specify which H four you want. So prop price there, find, and here is the price. So this is a price, but with the tags as well. And this is actually a list, as you see. Now, because we have only one price for each property, in this case, we are allowed to use the find method. So that would give us not results at least but the actual tech element. That means we can now apply a text object here, and we get that funky string there. So things are not that simple in real life, as you see, but luckily, all this object is actually A string. So it's a plain Python string. That means you can apply string methods to that object. So let me control that to remove the type. So in this case, what we want to apply is we want to remove all these characters. And a way to do that that I think about is replace. So you want to replace the backslash N with nothing. So just pass an empty string there and see what you get. Okay, these guys of this century 21 website have decided to make our life difficult. But how about applying? So we've got some space there white space, as you see, so we replace the white space with nothing, and we get the actual string. Great. So we sort of know that things are working well at this point. And for now, I'm just printing out the results. So as I already mentioned, it's good to first use print statements when you're building your programs, and then you replace those print statements with other functions that you want to use for this data you're getting or other objects that you're working with. So in our example here, later on, we will be adding some pandas methods to grab these values and send them to CSE file. So that's one of the first thing I would like to say. The second thing is that here now we grab the value of the first element. And now we start to think about being efficient. So we need to instead of going and extracting all the other elements like the property address and property state and so on. Maybe it's good to actually start building our for loop. So we now know that individual values are being extracted correctly. But now we want to make sure that a loop that iterates through all these properties is also working. And let's go ahead and start writing the loop in the other lecture. But for now, let's actually organize this code. So here is a trick you can use in Jupiter. So I go to the first cell and I'm in command mode. So you press Escape to go to the command mode and Shift and J, you select the other cell. J, again, select the other cell, or you can go up with K, so J, J, J. And what I want to do now is I want to merge all these cells in one single cell. And to do that with shift press, you press, so Shift M, and you get all the cells merged into one single cell. So this is more an issue of preference, but it's good to have a clean notebook there. So this is what we did so far. Let's go ahead and run the loop in another lecture. See you. 202. Scraping the Addresses of the Properties: So we've got the entire soup from the web page, which is actually the source code. And we also got the source code of the divisions with class property row. And now we were able to grab the property price for only the first division. So for only the first box here, now to get all the boxes, we need to iterate. So DD to delete that. And four, let's say, item in alloy. And actually, I would like to keep the all printed out here so that you can see what all is. So if you forget of that for a moment, you're able to see what it is. So it's like a list. So for item in all go here. So we'll be using the print method here. But I'd like to write it at the end because I don't want to add brackets now there. So it's good to have less brackets for now for you to see this more clear code, the actual code. So we're going through the first item, which is this division here, and we want to apply the find method to that item or just the find method because we have only one H four here. So find, and we want to find the H four, which has a class of prop price. And then what we want to get from this product is the text. And you saw that the text was a bit messy there, so we want to replace the backslash ends with nothing, and then another replacement there. So there was space, and replace it with nothing. So it's the same line as here. And then you want to print this out. So add a print statement there. And yeah, that's it. Let's see how this goes. Hmm. That was fast. So 725, 452. Yum. That's good. Alright. Let me delete this to save some space. So we have all already defined here. So we don't need to add it here. And let's go now and extract this zero gateway doesn't look very good example. So let's ignore that and extract this address here. So Winchester Boulevard, and that would be inspect Mm hmm. So that has a span tag with a class of prop address collapse. But you can see that you also have another class here, prop address collapse. So two classes, this is the address, and this is the name of the town. And look if you have other prop address collapses no. No, we don't. So prop address collapse. Let's add another statement here. Item. So those addresses are inside this method again. So item find. Now, if you use fine this time instead of Fine Ole, what the script will do is it will grab the first occurrence of prop address collapse. So it will give you the Winchester Boulevard address, and it will ignore the second one. So it will ignore Rock Springs. So that means we need to use fine O. And if you want to get this first line, you'd want to pass the zero index to this result set list then an index of one for the next line. So we'll do that. That was a span tag with a class of again, prop address collapse. So let me print this out to see what we have this far. So, here is the price of the first property, and then we grab the results set list in here, which actually has two elements. So the address here, and then the name of the town with a state code here and zip code. So that means we need to apply here zero index, if you want to get the first one, okay? And then Uh, let's see. So here is the first one, the first element. If you want the second one, you want to copy that on pases here and pass one here. Execute. And here we go. Ah, I guess you want the text, so you want to apply the text method there. Hm. Great. And just for the sake of visibility, let's add another line at the end of the loop to pass an empty string. So now you can see the blocks more clear, and we've got ten blocks there. Quite awesome, isn't it? So let's go now and extract the number of beds and the number of baths. So that is a span tag with a class info bed. And baths. Here's the other spin glass. If value full bath. Now, here we got an issue. No, we need to be careful here because we need to grab the number of baths here, which is inside B tags. But the number of baths is also inside B tags. So you can go ahead and apply a fine method directly in this level. So directly under O. But that would probably cause some problems because you have multiple Bs there. And so you've got also the area, which should be a bit tag as well. Span class. Yeah, it's a bit tag. So sometimes you have three B tags, sometimes you have more. So there may be two solutions there. You can either assume that bets are always the first ones and you can pass an index of zero to the result set list. So you get beds, and then you get full baths with an index of one and two for this square feet here, and three for this. But I'd prefer to do it in a more constructive way. So I'd like to go and extract these spend tags first, and then I go inside each of the spend tags and extract the value inside the B tag. So we've got span for info bed, and for full baths, which is this one here. Yeah, actually, this is listed as the third one. So beds are the first one and square feet, the area is second and then full beds and so on. So we don't have to think about the order of them. We only need to grab the class names. So info bet that means you want to access item, fine, in this case. So you want to find the span, and let's do first the beds, which was info bed. So let's print it out first to see if you are good to go. And so you get none for the first property. So this doesn't have any data for beds and baths, so you can't do anything about that. You just need to accept no data sometimes. And then here is the code, so the source code for the next one. Now, here's a trick. If you apply the text method to this object, so it should be here, that text, you get an error. And look closely what the error says. So it says non type object has no attribute text. That non type object was this here, so none, which is a special object, and it doesn't have a text method available. And so you need to count for that. And the way you count for these exceptions is by using a try and accept statement. So you need to Enclose this print statement here with try. So try this if it works. If it doesn't do this other stuff here. So which is pass. So just ignore these non types there. So again, try to get actually the text method out of this span text. And if that is not available, then just pass to the next iteration of the loop. So let's try that. And yeah, now it's working. Now, as you can see, we got the text for the B tag, but also the text of the span tag. So this is the text of the B tag, and this is the text of the span tag. So if that's fine for you, you can leave it like that. But I'd like to have the plain number only. And to do that, you need maybe apply the find methods. So we have, again, we have this source code, so we need to find inside that source code. We need to find the Bt tag, which doesn't have a class name, so we leave it like that, and we need to extract the text out of that bit tag. And that gives you the number only. So four, four, five, and so on. So that's good. Now, let's do the same. So I'll copy this block entire and we'll do the same for the number of baths. Let's make a space here. And for the number of that was so the area size. And this other thing here. So half baths. So we'll count for that, too. So info square feet, info square feet there. We go here like that. Then we have info value full bath. And one more for the half baths. So that would be info value half bath. Execute. We've got an indentation problem there. So Troy, this one is good. This one is not good here as well. So you need to indent the statements after Troy and the statement author except. So execute and let's see. Good. So four beds, and then four baths there. But then here we got the area or the property. So the order is not very good like this. In that case, we don't want to write pass here, but maybe we want to print none. In those cases, so print, none, print, none. Same here. Execute. And now it looks better. So now we know the order that we know that we have four beds in this property, and the area size is not available, and then we have four baths. And then we don't have any information about the half baths there. So that is looking good. And I'd like to stop here and get some more data in the next lecture. Yeah, let's move on. 203. Scraping Special Elements: Here we are again. And we've got this script, which produces this output. So we have some attributes for each of these properties. Specifically, those are the attributes of this block here. So price address and some attributes like the number of bets and so on. Now I'd like to go further and extract the lot size for each property whenever that attribute is available. So as you see here, some properties don't have a lot size. And while lot size is an important attribute to get to know from a property, in this case, is also quite a tricky one to extract from this web page. And the reason is that if you look at the source code, you'll see that this is the name of the attributes, so lot size, and this is the actual value that we want to extract. And both of these are inside this division. So the first line there. That division has a class name of column group. Now we have another column group class, so another division with the column group class here as the second line. Then if you look at another property, so another row of property. You'll see that this column group division is repeating here. So if you write a loop to extract the span with feature name class for all the properties, for this property, you'd be able to get the actual lot size. But for this other one, you'd probably get the age of the property, but you'd be expecting the lot size. You'd be getting the age of the property because the age of the property is the first feature name there. And lot size also is the first feature name. So with feature ename class in the second property. So this is one of those cases where you need to think about alternative solutions. So if you point to the column group method, so you say find all in division with class column group, and inside that, find the feature name with index zero, you'd get the first lines. You know that. Now, let's find a solution then. Well, how about looping through all these column groups? And then we check that if the text of the feature group is equal to lot size, then give me the text inside feature name. So in that specific iteration, again, if the feature group is equal to lot size or it has a lot size string inside the text, then in that current iteration, give me the text value of feature name. So we'll need a loop here. Inside our big loop. So this big loop here, let's call it the big loop is going through each of these rows. Then inside that inside the current iteration of that big loop. So let's say the current iteration would be going through this property. So inside that, we go to the column group divisions. So let's say four, let's call this variable column group in the current variable will be item. So again, item as we did there. I do find find all, actually. So you want to find divisions with a class name of column Group. Group. And let me quickly print out the column group variable. So just to see what we have so far. And here we go. So these are the data we have, and then here goes. Let me go up here. Here are the source code for each of the column group divisions. So the first division, the second division, and so on. So this is features which corresponds to this header here. And then we have architecture style, which is not what we need. We have roof type, so at each iteration, Python is printing out these lines. Now, what we want to do with these lines, let's keep the print there for a while. What we want to do with these lines is iterate through them again. So we will iterate through this div and we will iterate through this other div and we will see that if the text or the feature group in that current iteration has the string lot size, then we will get the text of the feature name for that current iteration. So again, we need a four loop here. Which will go through each of these column group divisions. So what it will do, it will access the feature group element and the feature name element as well. So for feature group feature name in and we need to use a zip function there. So as you may remember it, a zip function, which is a built in Python function is used to iterate through two list at the same time. So here is where you enter the Tolist inside the zip function. And our two list would be the first one would be column group that find all spans, so span with a class name or feature group. Similarly, we need to access the column group that find poll, and we need the span tag again. But this time we need a class of feature name. So don't confuse these variables with these class names. And here closes the zip function. So this bracket here. So after the four statement, you need the column here. Okay. Now, what do you want to do for each feature group? Well, let's temporarily print out the feature group text, for instance. And also the feature name dot text. And let me delete this. So this column group here corresponds with all this block of divisions. So execute that. We've got an invalid syntax here and look for the arrow. Yeah, here's a small arrow. So this one here is pointing us to this character, which actually is a semi column. For some reason, I put a semiclumn there, so it should be a column, not a semicolon. Okay, let me execute that again. So here is what we get. For the first property, for instance, we got the previous attributes, printed out. So no, no, no, for this first one. And then we have here is the feature group text, and here is the feature name text. And similarly, we have the feature group text here for the next feature group and feature name. And so then we have the next property there, which actually has quite a lot of attributes there. Heating fuel gas. And here is something you should know now. You should be aware about. Let me open again, Century 21 website. Rock Springs. So as you can see, the second property doesn't have this many attributes. So it has age appliances and basement, but not bad features and cooling, et cetera. So these extra attributes are somehow hidden in the source code of this webpage, and you can access them if you go. So if you click the link of the web page of the specific property. So here are all the attributes that we're seeing here. So fireplace count two fireplaces. Here is fireplace count. And you can also see that the lot size is listed in the property webpage. So here it is. Which is actually a good thing. So we are being able to extract all the attributes of a property without having to go inside the property web page, the property link. So that's a good thing. And now, what we need to do is, let's keep the print statement there for a while, and we need to check. So here under the four loop, if lot size in feature group that text. So, for instance, is the lot size string inside this feature group text? If it is then give me the feature named up text. So it will give me the value here. If it is not, then just don't do anything. So we leave the loop as it is. So let me delete this function now, the print function that we executed earlier and execute this. So here we go. We've got nothing here. These are previous attributes. And then we have four attributes here, and then we have 0.221 acres. Here we got half an acre. Okay, that is looking good now, and I'd like now to go through the next lecture where you learn how to get rid of these print statements and to actually store all these attributes in a table, so in Panda's dataframe, then we export the data frame simply in CSV file or Excel file, whatever you like. So we're going to have a price column there and address column, a state column with a zip code, and also columns with these attributes of a lot size as well. So let's move on. 204. Saving the Extracted Data in CSV Files: Now, let's think about how we can add all these values. So these values into one data frame, pandas data frame. So I thought about having like one, two, three, four, five, six, seven, plus the lot size eight columns in the data frame. And then for each row, you'd have, like for price, you'd have 725,000 for this, and then the next one for 152,000, and so on until all the properties are consumed. So I hope the structure is clear and how to do that now. Well, one solution would be to maybe iterate through the data frame, but that's a costly solution. It takes a lot of time, so the process may become slow when you iterate through data frames because data frames are not built to iterate through them. So it's probably better to create a data frame out of Python dictionary or out of a list of dictionaries, maybe. And actually, that's what I'm going to do. At each iteration, what I'll do is I'll add these values to a dictionary. So for instance, I'll start with the first dictionary. And so in the first iteration, I'll have a price key and the value of the price as the first pair of the dictionary, and then the next pair of that same dictionary would be the address key and the address value. And then we go to the next pair. So we add the third pair here, and then a fourth pair fifth, sixth and seventh and eighth. So pair a dictionary of eight pair in the first iteration. Then in the next iteration, I need to create yet another dictionary with the same keys. So we'd have, again, price and the value for that price, which would correspond to the value of a second property. And so I'll build a second dictionary and then third dictionary, and so on until all the ten properties here are consumed. So I'll end up with ten dictionaries. Now, you also need to store these dictionaries somewhere because if you just iterate through dictionaries and you lose them at each iteration, then you haven't done anything. So what we'll do we store those dictionaries in a list. So the first thing you may want to do is you want to start each iteration with an empty dictionary so that you can add the key value pairs to that phrase dictionary. So once you create an empty dictionary, then you go ahead and replace these print statements. So you'd want let's say price as the key of the first dictionary, and that would be equal. If we don't need the brackets, this one, either. So that's it. Similarly, you can do this was address. Remove that again here. Let's call this locality. So we are creating keys on the fly, so price address and locality, and we are assigning values to those keys again on the fly. So maybe it would make sense to have price down here. So we start with address, locality, and then the price. That would be the beds. And if there are no beds, then you need to pass none for the beds. And then, again, that would be area, which is equal to these again. Same thing for area, no when there is no area and one more here. Full baths. Let me copy this. None. And they would be hot baths. Equal to none. We have a print segment here, which we don't need. So here we are going through each group feature name if lot size in feature group text, then the let's call this lot size. Is equal to feature name text. And let's remove this print statement. And so at the end of this loop, you'll have your first dictionary. So at the end of the first iteration, you'll have your first dictionary. Now you want to store that dictionary somewhere. So let's store it in a list. So normally, you need to create a list outside of the loop, an empty list there. And then at the end of the loop, which is exactly here, you want to append the dictionary. So you'll get a list of multiple dictionaries. In this case, you'll get a list of ten dictionaries. Let's execute this. We've got an invalid syntax there, bads. I forgot to have the assignment operator there, and right. No error this time. Let's print L here. And it's looking good. So you can check the length of this. So it's ten. Now, if you want to throw this list of dictionaries to a data frame, this list to a data frame, well, you'd need to use Pandas, and then DF is equal to pandas data frame. And here we need to write a really long statement. I'm jogging. You just need to pass the list there and you create a data frame out of that list of dictionaries. So let's check the data frame. And boom, here are the data. And as you can see, we even got Nan values when there is not a lot size. So Pandas understands when there are no data in the dictionaries. So, for instance, here we didn't have a lot size, and Pandas will assign a non by nan value for that, which if you want, you can simply replace with a non value. Then you need to work a lot to save this to a CSV file. A really long statement. Okay, so I'll put that CSV, and it should be good to go. Let me check that. Here is a file. And here are the data. So it's looking good. Great. Now, what comes next when, as you might guess, we need to go and get the properties of all the pages. So second page and third page. So we'll do that in the next lecture. See you. 205. Crawling Through Multiple Web Pages +: Great. So we got the script working for one page. So for the first page, but we may have multiple pages there. So, for Rock Springs, we have three pages with 28 listings. So 28 properties listed there for sale or for ends. Actually, they are for sale, so homes for sale. So this is the second page with ten more properties, and then you have the last page there, which should have eight properties. So we have 28 in total. Now, this is a small town, so it doesn't have many listings there, but with big cities, you'll have lots of pages. And the script that we'll be building to extract property data from these pages will work with any number of pages. How do we go about grabbing data from all the pages? Well, there's no magic there, but there is a single trick. You know, if you search again for Rock Springs, you'll see an initial URL there, which we loaded in Python. I think it was without this K equals to one. It was like this only. So I'm not sure what the meant there, but anyway, maybe it was because I searched again for rock springs. So this is the first page. Now, the logic behind extracting data from the other pages is what we need to do is we need to load the other pages in Python as well, using request again. So just as we did here, we loaded the first page. Now we need to figure out a way to load the other pages. We can either go manually through each of the 300 pages, three pages in this case, and copy the URL, or we can try to figure out a way. So to figure out the rule, if there is a rule that the URL changes when you switch through the pages, and it probably always be a rule there. So we need to find that out. So I went to the second page, and as you see, now the URL changed with some extension there. So T equals to zero and C equals to zero. If you go to the third page, you see that the URL before 20 didn't change, but C was changed to 20. Now, if you go to the first page again, you'll see that S is equal to zero. So when you search for rock springs directly, you get the base URL there without this extension. And then if you go to the first page, manually by clicking the number one here, you'll be included in the rule that changes the URL when you move through all the pages. That means we can use this URL to grab the first page, and then we can loop through the URL. And change this value to ten as we iterate. Increase by ten. So from 010 and 20, and if we have more pages, that would be 30 and so on. So I hope you get the idea. Let's now go ahead and let's see, so let's store a base URL there. We should be something like this without the number. So this is the stat URL. And now before we request the source code with requests, let's first try to build URL and print them out. So we're using a print statement as always to try things out. So let's say for page in range, well, the range should start from zero, and up to we had three pages there, and the last page had an of 20. So maybe put 30 there and then iterate with a step of ten. So at each iteration, we will increase by ten. For now, don't worry about the number of pages. For now, we are just putting a value manually, so we know that this has three pages, so I'm putting 30 there. But later on, we will change this to actually a variable that grabs a number of pages from the website. So if instead of Rock Springs, you'd have New York and you'd get probably 200 pages. So you want to grab the number of the last page 200 and then pass something like 200 times 20 here, so you get 2000 and you get a loop that goes to zero, ten, and up to 2000. So we'll do that later. For now, print? Base URL plus. Well, this page variable would get an integer. So we need to convert that integer to string using the string method. And then page goes inside that. So let's try this out. Ana, these are the threelings. Let me open one of them. Here we go. And this is the second set of results. So it's page two. Great. Let me close this. But of course, printing is not what we're interested about, so we don't want to print the URL. We want to get the source code of them. So what you want to do is are equal to requests. So you're inside the loop, and later we will merge this loop with the other code. So let's focus on this for now. Get base URL plus the string of page number. And just off of that, you want to grab the content of request and also make the soup. So beautiful soup, C and HML parser. And for now, let's try to print out the prettified version of the soup object. Great. And that took a while, but here is the result. So in the first iteration, we got the URL printed out by this function, by the print function, and then we got the prettified version of the source code for the first URL, which is quite long. So anyway, you get the idea. So that seems to be working, but what we need from all the source code. So we have the source code of all three pages. So we don't need to print all the source code, but we only need to extract the property row divisions. So just as we did here, so we got the soup for first page and then we created an all variable there. So we do the same here. But this time, it should be indented because it's inside a loop. So all and property row class division, that looks good. So if you print it, just to check all here is the result. So the first URL printed out, and then you have these divisions. And then you have quite a lot of data here as well. So now, what you want to do is you want to grab all the code that you just build there and maybe delete this and delete the entire cell, and you want to put that code up here. Great. Now, next thing is, you did this for one page, and now you're looping through all the pages. So what you want to do is you want to indent all this block on the right so that this block becomes part of the four loop there. So control and closing swear bracket to indent selected text. So now, this loop here will run as many times as there are pages there. So what can we do now? Well, we can try out the code. So let me execute this shift enter, and we have to wait a bit here. So that looks like it's working. And so at this point, we should have the L list there with all the data. And here we convert that L list to a data frame. So let's execute this. And then here we execute the data frame. So let's see now. Yep. And so we have 425 rows because we start from zero. But we had 28 listings, actually. So that means these last three properties have not been listed here because something happened there. So we are in page three here, and the last successful one was Wen Avenue. So we look for Wende Avenue here is Wende Avenue. So it has an address and the locality Sook Springs. And then the one after that, it has only the locality there. So in that case, what you could do is you could try to handle an exception here in the code. So for this one here, we could say, try to do that and accept DcaliT equals to none. And now I'll execute this again. Let's hope we don't get an error there. Yeah, that was successfully executed. Execute that on the data frame. And let's see. Yeah, now, we seem to have 28 rows there. So that seems to be working. And the last thing you want to do is, you know, instead of passing this range manually here, we could add actually a variable that detects a page number. And all we have to do is we go to our website. Let me remove this. And so you want to figure out where this last number is being rendered. So that is the indicator of the number of pages. So we have three pages in this case, inspect that and so that brings us to this point. Actually, in this case, it says page, current page. So let's go to the first page. And let me close this. So we are supposed to be at the first page when we are on the script for the first time. And in that first page, so we want to grab the content of the first page, and then we want to know the element of that last number there. So we see that that's the a element with class page. And here is the text so three. That should be actually the last element with a class of page. So you'll have quite a few elements with class of page there, and this should be the last one. Yeah. So that should be the last one. So we keep that in mind, and we go here, and what we can do here now is or let's grab that page number in here. So page let's call that page number. That would be equal to soup. So soup will contain the HML code of the first page. So this one here, which is not an Ajax request. So it's just simple one of this page. And so we want to find all A elements with a class. Of page. And so if I print it out just to see what we have so far, page number see where you've got a few elements there. But the last one is the last page number. So three, that's what we need. So we need to grab the last item of the list, which means minus one, an index of minus one and text. And yeah, we got three here. And so we need to transform this number now into 30. And the way you do that is just page number times ten. So that would give you 30. Well, almost because this page number is actually a string here, you know, type another bracket. So it's type string. And that means you need to add integer here. So you want to convert this string to an integer and then multiply it by ten so that you get 30. So that should do it now, and everything should work, I believe. So let me execute this. The URL are being printed out and the script finished. So when you don't have the busy text before the title of your file here, that means the script is running. So now we don't have that, so the script finished. Execute that. And this is our results and export it to a CSV file. And let's check. So I put that CSV. And here is the data. So we don't have any reputations here. No, everything looks unique. That closes this section of web scrabbing. So if you want to find other localities, so I tried this for rock springs, but you can try it with any other localities. So all you have to do is change the URL or you could even implement some user input so the user enters a name, and then you construct the URL, and then you pass the URL in here. So we don't need this, clean this up as well. And if you want, you can merge this cell with this one. So you can execute the entire script in one cell. And you can also save this. So download it as a Python file and you get all source code. So the Python script. And plus these lines but with a comman hashtag. And you can run it as a entire script. So I hope you enjoy this. I know this was quite a bit to digest. And if you have questions, please ask them. I'd be happy to help you. So I hope you learned a lot from this, and we'll move on through the next sections, so we still have very interesting things to do. And I'll see you later. 206. App 9: Django & Bootstrap Blog and Translator App +: Hey, welcome to a very informative lecture, especially about those who are interested in building web applications with Python. As you may know, Python is used for different purposes from automating routine tasks in your job. Let's say you want to generate PDF reports automatically, send automatic emails, et cetera. Then you can use Python for data analysis and visualization, data science, and machine learning, but also for web development. So building web applications with Python. And here is where I would like to stop and explain you how exactly Python can be used in web development and what Python web frameworks you should use. So I just mentioned the word web framework. So what is a web framework? Well, with Python, you can build applications either by using plain Python or by using one of the Python web frameworks, which are basically Python libraries that you install with PIP. And these web frameworks make it easier to write web applications using Python. Now, I can tell you that creating a web app without using one of these web frameworks is like reinventing the wheel. Because if you don't use a web framework, you basically have to rewrite all the code that the authors wrote the authors of these web frameworks wrote. So instead, we just install these web frameworks, and then we use that code. That is inside the web frameworks. And that code is usually things like handling HDP requests and delivering web pages on the browser. So routine low level tasks. But instead of dealing with this task, we want to focus on building the functionality, the practicality of our web application. So creating the input boxes, for example, for our forms, sending users from one webpage to the other, so things like that. So you should use a web framework. So I guess we have clarified that point that you should use one web framework. Now, the next question is, which of the web frameworks you should use? Well, there are many web frameworks for Python, but I'll only focus on three of them, which is flask, jango, and just Pi. Let's start with FLASK. FLASK is a web framework usually targeted for building small web applications. For example, let's say you just want to build a small translator that translates from one language to another. Think of Google Translate. If you just want that web application where people go to your domain, let's say, translator.com, and you just have those two boxes there, people will type in the text in one language in the first box and get the results. So the translation in the other box. So that would be a small app. Another example would be an app where you convert, let's say, JPG images to PNG images. So people upload an image in JPG or vice versa. So FLASK handles all those uploading and processing on the background. On the background, of course, you'll probably need an image processing library besides FLASK. So you'll have to install Pip install Flask and maybe Pip install CV two, so open CV to do the processing. But the serving to the website to the web app will be done with FLASK. So FLASK will get the original image, and it will get the output image from OpenCV and it will serve the output image for download on your web app. So these are small web apps. Now, don't get me wrong with FAS, you can also create bigger web applications and what I mean by bigger web applications. Bigger web apps, I mean things like, let's say you have a blog website where you add blogs every week or every two days or so. So you have maybe several authors who write content for your blog. For that block website. So we're going to have different blocks, and all these blocks have to be saved in a database. Now, Flask can do this, of course, but Jango would do this better. Jango would do this better because it is easier to work with databases with jango because it has a better level of abstraction. So with FAS, you can also do this with FAS, but it's more work. You have to do more routine tasks for FAS. And jango would also allow you to add more apps in that website project. So we took the example of blocks. You'll have blocks in your website, but maybe you want to add another feature. Let's say you want to add a translator there. So Jango can also build a translator. On top of that existing website. But if you just want to build a translator alone, then jango would be an overkill. What do I mean by that? By that, I mean that for smaller web apps, jango takes more work to set it up to set up a jango project. It takes more work. But once you set up a jangle project, then things go smooth. But for smaller apps, it's good to just create a FASk application. It's very easy to create one. So that is the difference between jango and FASC. Now here comes Just Pi. Just Pi is a very new framework. And why did I include Just Pi in this set of three web frameworks? Now, Just Pi is quite special. What do I mean by that? Well, with FAS and jango, you also need to know HTML and CSS to be able to build web apps because every web page that you see on Internet, it's built on HTML. So all the text and input boxes and buttons. All those are built in HTML code, which is very easy. So don't get scared about HTML. It's a very easy language to learn. But I'm just saying that you cannot create the front end of a web page with Python. So HTML is for the front end. And then CSS is to beautify to prettify the look of these HTML elements. So the text boxes, the text, the colors, all these can be made to look nicer with CSS. So CSS is also a language which is also very easy to learn. So you'll have to write some CSS and HTML code and save that code in HTML and CSS files respectively, and put those files inside your web app, be it in jango or Flask. Now, here is where JSPi comes in. JSPi allows you to create web apps without writing any line of HTML and CSS. But Juspi is very new. It's a new framework, web framework. And as I said, the good thing about Jpi is that you don't have to write HML and CSS because JSPi has some specific Python objects. Let's say, it has a DIF to create these divisions where you can put texts and things like that, or it has a button object, Python button object to create a button on the web page. Of course, the downside of this is that you are not very flexible as you'd be with FLASK and jango. Again, I would say Jpi is also for small web applications. If you want to build a blog website with lots of content, Just Pi is not the best choice. It doesn't work very well with databases as much as Jango does or FLASK. But again, if you just want to build a small web app and you don't know CSS or HTML, then Juspi could be better than FLASK. So that was an overview of three web frameworks for Python. Now, all these three web frameworks are covered in the course in this course. So we will build at least one web app with each of these three web frameworks, and it may be tempting that you want to watch only the videos of the web framework that you like, but I'd recommend that you don't skip any of these web frameworks. Saying that because if you want to do web development with Python, then it's a good idea to be exposed to different web frameworks. Each of the frameworks does things differently, so you will learn a good deal of web development. For example, FASC does things a bit more low level and raw, and that helps you understand web development from a deeper perspective. But then you learn about jango and you'll appreciate the high level of abstraction that jango has. You'll appreciate how easy it is to make changes in your web apps. When you use jango because of that high level usability. So jango hides some things from you, which makes things easier, but you will not understand some of those things. So that's why you should also learn Flask. And also Jus Pi is very fun to learn. And I'd recommend Juspi especially for someone who is not interested to become a core web developer. So maybe you are a data analyst, but you just want to make a web app where you show some data, some visualization on that web app. In that case, Jus Pi could be actually the best choice. But if you want to be a pure web developer, then you want to learn jangle and flask. Then when you have to build a web app, you can just pick one of the web frameworks which is best for that project or maybe the web framework that you know better. Why not? I hope this helps. I'll talk to you later. 207. Setting Up a Virtual Environment: Hi. In this video, you will learn how to create and use a Python virtual environment. So what is a Python virtual environment? Well, it is just a copy of your Python installation. So, in other words, a copy of your Python interpreter. So when you download Python from python.org or from Anaconda, you are downloading a Python interpreter. Now we make a copy of it. Why do we make a copy? Because with Python, we may write different programs. And for each program, we might need to install different packages, so different libraries. And usually we install these libraries in our main Python installation. So in the interpreter that we got from python.org or Anaconda, that is also referred to as a global interpreter. But by making a copy for each program that we built, then we install libraries only for that copy of the interpreter. The benefit of this is especially for web applications because when you create a web application, you will deploy it later in some online servers. And when you make a copy of the interpreter and then you install the libraries you need in that copy in that virtual environment, then you have a clear list of the libraries that you have installed. So you can generate a list then you can give that list to the server where you will deploy your web application. So that server will get the list of libraries from that list and install them. Now, the benefit here is that if you had your global Python installation, you'd have many, many libraries. So that server would have to install all those many libraries. Which is not a good idea. So why not having one interpreter for each Python project. So now that we are about to create our jango app, we are going to create a virtual environment first on Visual Studio code. This is how you do it. So first of all, I'm open Visual Studio code. So this is the welcome page. I haven't created any project yet. So I'm going to go and create a project which is basically you just open a folder, a directory. In Visual Studio code. So go to File and then go to Open folder or open depending on what operating system you are. So this can either be open or open folder. Click there and then locate an empty folder which you should have created before. I created this empty folder jangoblock translator. You see it's completely empty. So I'm going to press on open and that will open that folder. Here you see here in my explorer tree on Visual Studio code. Now that we have the folder. So in this folder, we are going to put all the files for our jango project, including the copy of the Python interpreter. So the virtual environment. To create this copy, this is how you do it. So first of all, you need to open a terminal and you have to do a check first. So make sure what Python you are using. So in my case, I use a command, Python 3.9, and that opens Python. So this is a global Python installed on my computer. So I'm sure that this command is working fine. In your case, it could be just Python without 3.9 or Python three. It depends what you have been using. So wherever you have been using I'm going to exit this interactive shell. So this was just to try out the Python command. Now I know this is working, so I can go and do Python 3.9. So no spaces here. Then a space, the flag, then V then NV. So what is this? Well, VNV is a library that is installed. By default, it's a standard library for Python. It comes shipped with Python. So I am using that library. So when you use that command, Python 3.9 or Python, and then you use that flag, that means that you are about to execute that library as Python scripts. And then this end is the folder where the copy of the Python interpreter will be placed. So press Enter. And you see immediately that N was created this folder here. And if I expand this folder, you'll see there are several other folders in here, and inside this bin here, you will see that we have the Python exectable. So that is a copy of Python. It can either be used as just Python or Python three or Python 3.9. But I'll show you how to use that Python instead of a global Python now. So don't do anything with that folder. Because what we want to do now is we want to select a default Python interpreter for this particular visual studio code project. To do that, you want to go to the Command Palette. You can do that with shortcuts, actually, on Mac, it would be command shift, P, press the three of them at the same time. On Windows, it would be Control, Shift, P, so that will show this box, and then you can type in there Select interpreter. So this is what we want to use Python Select Interpreter. That commands. Click on there. And you will see this list. So I have different Pythons in my system. One of them is this visual environment here that I have just installed, and that is the one that I want to choose. So press there. And now you should see down here that Python 3.9 0.6 in my case with this folder. N is the folder. V is the virtual environment library. This now will be used as default Python. Does that mean? Well, that means that if you now type in Python here, but first close this terminal and open a new one, so to have a refresh of terminal, new terminal, you'll see that now before this tag here that tells me to write something here, I have this in parenthesis. That means that this Python virtual environment is being used. Now if I just type in Python, Python 3.9 0.6 of that virtual environment is being used. Let me exit. I can also type Python 3.9 and the same will be used. Any of these commands here, Python, Python three or Python 3.9. So make sure you have that there. So how does this work? Because it looks like magic. Well, it works like this. Let me close this terminal again and open a new one, new terminal. So you see that here we have a command being executed by visual studio code when you open a new terminal. So it says source, which is a command to activate the virtual environment. So source and then the path to the activate file. You see it's jangoblock translator, which is this folder. N B Activate. NBN Activate. This activate file is being executed, and that is the command that sets the environment to this virtual environment. That means also that you can use Python both from here as an interactive Python shell, but also if you want to write a file now. So let's say create a file. So be careful here. I'm going to write Hello PY. I'm saying be careful because what happens is that this file was created inside my NV folder. So that is not a good thing. You don't want to touch the F folder. So I'm going to delete that file and recreate it. To avoid the file being inside the Nfle, you want to first press escape, and that will take the focus out of that NF folder. Then you can go here and create the file. Now you see that the file is created in that root directory, so jangle block translator hello dot PY. And if I say print hello here, right. And now I can execute this file using these green triangle ears of the round bottom. Press that and the file will be executed using the virtual environment Python. So you see here what happened on the background. So again, to wrap it up, the virtual environment was used when we opened the Python Shell. It was also used when we executed the Python file, and it's also used if we install third party packages. So let's say PIP install jango to install jango. That jango will be installed for this particular Python, not for our global Python. And I can prove you that by going to N and then to Lip and you will see that jango was just added to the third party packages in here. So JangoT is what we just installed. To get rid of this warning, you may want to execute this command as being suggested Python 3.9 or Python directly, PIP install, dash, dash, upgrade, PIP to upgrade local the virtual PIP, so to say. Right. And now, if I close this project, I and open it again. Then I can go back to my previous project either by using this recent section here, so clicking on that or by going to File, Open recent and locate the project there. Or a third way would be again to go to File, Open and go again to that folder, so to the root directory. So those are and hello dot PY and press Open. And the same project will open again, but you have to close the current terminal and open a new one. In order to get the virtual environment active in the new terminal, you see now we see this end here. And, of course, now you can also execute that file again, and the virtual environment will be used to execute and get the output. So that's how you can use virtual environment in Visual Studio code. Thanks. 208. Creating Django Project: Hi, welcome back. In this video, I'll show you how to create a jango project. What is a jango project? Well, when you create a web app with jango, first, you want to create a jango project, which is a set of files which are generated automatically by jango. This is what I'm going to show you now. So these are the project files. But then you can add apps to that project. So you have one project, but you may have several apps. For example, in our case, we're going to have one project, but then we're going to have the block app and the translator app as well. So two apps, one project. Now let me show you how to create the project. To do that, you need to have installed jango and preferably to have a virtual environment. I showed you how to create a virtual environment in the previous video. So I have this folder now, the root directory, the folder, which has a virtual environment, the lot PY file, which I'm going to delete because we don't need it anymore. So I have jango installed. That means I can now create a project using the jango admin command. So jango comes with a few commands which can be used to perform different operations with jango. So Jango admin this command, along with start project command will create a jangle project, and then you need to give a name for a new directory that jango will create. Let's say my side. And then space and a dot. The dot means that the current folder, which is jangled block translator, is a project folder, so it will place the files in this directory. So execute that command. And this folder and this file will be created. And this folder has some other files inside. So what are these files now? Well, we have this init file, which is an empty file, and in here, it's optional. Maybe later, you can place things that you want to be executed immediately when the program when the web app starts. So I'm going to leave that right now, we are going to leave it empty. And then we have this Sg file, sosg dot PY. This is a configuration file that you might want to change later on when you deploy your jangle app in anSG server, and there's also another type of server. So it depends where you are going to deploy it. The other type is Wiz g server or Wiz G, if you like this one here. So that's the other configuration depending on what kind of server you're going to put your jango project so that it is in an online production server so that everyone can see it. And then we have the settings that PY file. This is going to contain all the settings so for example, the time zone, the place of the static files such as images and CSS files, we're going to cover these. So don't change those. And then we have the URL, that's PY file. This will have basically the URL of your project, how the URL will be rooted and so on. So that was my site, and then we have managed that PY. This is file that you don't normally change, so it will be staying like that. This is useful now when you start your new Python website. So we just built a jangle website and we can see it so we can start the app by doing Python manage, that's PY. So we execute that file with Python and using the Run server argument. Execute that we have this warning. We are going to fix that in just a bit. So this is website URLnow. If you press Control or Command and then click there, that will open your new website. So it doesn't really have an app and custom app now because we are going to addit later. But basically, this says that it's working. To stop the app from running, you should press Control C on the terminal. And now, this message here. Well, this message is saying that we need to execute some SQL command. Now, this is a good thing with jango because you don't really have to execute any SQL query language. You can just do Python manage PY migrate. Press that and jangle will execute those queries for you. So basically, these are queries that create some default tables, database tables. You can also see that a new dbdt S three file was created when we executed Python manage PY Migrate. So what that command did was it created an SQL database file, and Jango by default uses SQL three, but you can also use postgrad SQL. But you can do that. You can easily do that on the production server. Locally, it's good to use SQLite three, which is just one file and all the data will be there, all the tables of your project will be there. So that command generated that file. And it also applied all the changes required for the initial phase of JangoPject creation. So it's created some tables, and later, maybe you want to make more changes to your tables. I'll show you how you create new tables through jango not through SQL. So through Python, it's very easy. And once you create a table in the Python code, you have to run that command. So that will translate your Python code into SQL queries. So you don't have to write SQL queries with jango. You just have to write some easy Python code. I'll show you how to do that when we create the app later. For now, I can show you what tables were created inside this file. If you double click it, it will not be displayed because Visual Studio code doesn't display SQLite databases. You need a proper program to see this database. You don't have to see it. I just want to demonstrate to you what data this has inside for learning purposes. So I have a program here called DB Browser for SQL Light. You can search for that on Google and install it or just see here what's what I'll do. You don't need this program just to see the data for curiosity. So you want to open the database. So that is DB Sculi three that we have the file. And so you see that there are several tables here. These are tables concerning the admin interface, actually. So no tables are being created yet for things like blocks or other features that we are going to have for our jango project. So things in jango are saved in databases, and Jango uses culi three by default, as I told you before. Each of these tables, of course, have data so you can go to browse data and browse these tables. For now, they are just empty because you see, it's just empty. We haven't added any users to the admin interface yet. So what is the admin interface? Anyway? Well, let me start the server again. Go to the website. And if you go to the URL, so after the port, you do slash, and then Admin. Enter, you will see this login box here. You need the username of the admin and the password of the admin. Currently, we don't have an admin user created yet. That is also why you see all these tables are empty. So not data. So there are tables, but there are no rows in these tables. So later on, I'm going to show you how to create an admin user. So why do we need the admin interface anyway? Well, we said that we are going to build a website that contains blogs. Now, who is going to add content in these blogs? Is it you the developer or maybe some authors who writes content? So these authors, there are two ways to write that content. Either they go to your visual studio code project, and then you show them the Python files where the content or the HML files, where the content will be written or a smarter way is to have a friendlier interface where you have these content boxes and you have options to change the fonts. So buttons and toolboxes and things like that. So a real word processing experience like Microsoft Word or other word processors. So it's easy for authors to add content continuously to that website. So you give those authors ad me login username and a password so then they can go to your website and add we're going to look at the admin interface in the next video. So that is what we had for now. Thanks for following. I'll talk to you later. 209. Creating Database Model for the Blog App: Hello again. In this video, we are going to add some codes into our models that PY file. As I explained to you, a page a web page has a model, a view, and an CML template. So the model is lower in this trio structure. Therefore, we are going to start with the models. What we need to create is a class to represent a block post. So let's call this a post. Now, post is not a simple class. Post should be a class which inherits from models module. So that makes this class a model class. So module is a specific class which is designed by the jango authors, the developers of jango and it's designed to contain fields of data. What do I mean by that? Well, for example, we said that we want a title field. A webpage is a title. So that title, when the content creator creates a title, that title will be stored in the title field of the post table. So you showed I showed you this DB Viewer, which is a program to see data to view the data of an SQL database. So the SQL database is this one in here, db Q three, and this post will create a new table in the db dot Sculi three database. Now, these are the tables currently, so there's no post table here, but you'll see that one will be created when we complete this table. So title now is models What is a title? Is it a care field? Yes. I think this type would fit a title. So this is a database field type, and it gets a max length attribute. Let's say, 200 characters. So there will be a textbooks that will allow up to 200 characters for the title of the blog. Then what else do we have? Content. So the body of the block. Now, here I wouldn't go with care field because that is designed more for things for small pieces of text. This would be more like a text field. And you can leave that empty. What else? Well, date, created, maybe we should be modules dot date time field. So you see that this models module of jango has all these fields ready. So a date time field would be auto now add equal to true, which means that when the content creator will be creating a new block post from the admin interface, so they will be writing a title, a content. And then there will be a save button there where they can press that save button and the post will be live. When they press, when the content creator presses that button, this class will be instantiated and it will generate the current date and time, and that current date and time will be injected into the date created field of the post table in the db Suli three database. The database has several tables, pos is one of the tables, post has several fields. One of the fields is that. Okay, I hope that makes sense. Then we have a slunk field, which will be recording the part of the URL after the domain. So as we said, if your domain is example.com and your blog post is about dogs, then the slug will be slash Dogs. So the complete URL would be example.com slash DGS. And here, the user, the content creator, will just write dog or wherever they like. So the content creator will enter the slug in the admin interface, just like they do with title contents and other input boxes there. So slug would be models again dot Slug field. So there is a specific class that represents slug field in jangle called slug field. Let's put a maximum length of 200, maybe. It makes sense not to have very long slugs. So this will not allow the content creator to enter slugs longer than 200 characters. And it has to be unique, so unique equals to true. If admin, the content creator enters a slag which has been entered before, that would not allow the new slog to be created because you cannot have two pages with the same URL. I would mess things up. Therefore, this argument doesn't let duplicated URLs to be created. Then we have the author so author the variable name modules dot four in key this time. Why? Because we are going to get this value from another database table, which has already been created by Jango and we can get that from jangodt Ctrip dot. Of models import. So from that import, user, right. This is a class also, you can see it when I hover the mouse. And therefore, in the two arguments here, we need user. Without the parenthesis. So basically, a foreign key field type means that the value of this database field will come from another database table. In this case is a user database table. And this field will create on the admin interface a drop down list where the content creator can choose between different user names. So it happens automatically. But we want to specify a few parameters on delete the behavior that will happen when the user is deleted. So this user is deleted from the original database table. So cascade, but you don't need this, so delete that and just leave it like that. Now, what does this mean? Well, this means that if a user is deleted from the user database table, the user posts will also be deleted. This is what cascade does. I'll delete this comma here, and the last field we want to add is status, the status of the post, which would be equal to models that integer field. On the admin interface, there will be a status dropdown list which will contain two options. Draft and publish. So the content creator could choose to save that article either as draft or as published. So this would make it easier for content creators to organize blogs because they could save an article as a draft and then in our jangle we could make a conditional not to publish such articles that have the status as draft, but only publish those who have the status as published. So this would be a good way to distinguish between the two types of posts articles. So we have to have choices, which is equal to a variable, let's say, status and what is status? Well, status has to be a variable we have to create here. So status equal to a topple of two topples. One would be, let's say, zero trougt. The other one would be one publish. And the default one would be maybe draft. So zero stands for draft, and one would be for publish. Now, the admin, the content creator will see either draft or publish in that dropdown list, and that completes our class post. Now, make sure you save this file, file save or Command S or Control S, and then you need to do something here. We need to apply that model to our database. So we have to run some SQL queries. But as I've mentioned before, you don't need to run SQL queries explicitly. All you have to do is run two commands, Python Manage dot PI make migrations so currently, if you have a look at the DB browser program where we see the data, we don't have any tables called posts for now, even if I refresh this refresh, there's no such tables. But now see what's going to happen if I run this command. Okay, something happens here, migrations were applied, so the database structure was changed, and then we need to add another command, which is that Python manage dot PY, migrate this time. So that one and that one we apply SQUAR queries corresponding to this model. Now, if I go to here, refresh you will see this table has been added block post. So the name of this table was constructed using the app name which is block, and underscore, Sol Jango does that automatically, and then after the underscore, post, which is the name of the module. So if I select that table, you see now that we have these database fields. So here we see all the fields that we create. ID is a field that is created automatically, but we have title content, date created, slog status, and author ID. Right. That completes the creation of our model. Now we need to create a view. Let's do that in the next video. 210. Views in Djago: Hi. Previously, we created an HTML template, which is basically responsible to render the content on the browser. But this HTML template should be somehow connected with the models that's PY file. This HML, template has some variables which are waiting to be filled with content with values. So title has to come from the database, from the SQL database, which is this file in here. Therefore, we have to find a way to connect template with that database. And since in Python, this class post is the representative of that database table, therefore, we need to connect Block that HTML with this class post. I is where the middleman view comes in handy. So we go in views and we create a view. Let's call this block view. You can call it wherever you like. This is just a name for the class. But I want to distinguish this name from the other classes so that it's easier for you to understand things. So class block view. It's a very simple class, actually. It should get a model variable. So Jango expects from this class to have a model variable, and this model variable should point to the name over the module that should be connected to the block. So basically, we have, again, a module variable and also a template. Name variable. So this is what this class does. That's all. It connects the model to template. The model will be post, but post is not an imported name in this name space, so we need to import it from models, import post. You see now post is available. Therefore, now this line is valid. And template name, all you have to do is just give name over template, which is blog dot HTML. And that's it. Alright, so far so good. So if we run the server now with Python manage that PY Run server, but be careful. I'm not in a virtual environment here, so close that and open a new terminal and do again Python manage that PY Run server. And sometimes you get errors such as this one in here, templates dear OS is not defined in settings. So go to settings, we just here, and we need obviously OS the OS standard library, which does directory operations with folders and files. So we needed that when we declared the templates dear variable previously in here. Save the file and run again. This time, the server started. So this is the home page, but there are no web pages other than this. For example, if you go to Dogs, you get an error because or dogs or cats. Of course, we don't have anything because we have no entries in our block table in the database. What I'm going to do in the next video is I'm going to enter some dummy data in our database table through a program called DB browser for SQL Light. If you don't have this program or you don't want to install it, that's fine because this program is just optional, but you can install it for free, or you can search for it on Google. Normally, we want to enter the data through Admin, but just for testing things out, I want to quickly have some data now so that I explain to you what's going on, and you understand how things are working. So see you in the next video. 211. URL Patterns: Hello. Previously, we created a view which is a class that connects the model with a template. Now, in this video, I want to enter some dummy data in our database table. So our database file is DQ three, and it has several tables inside. I want to use the DB browser for SQLite and then go to open database. And then this is a root directory and go to db cul three and double click there. Then you want to go to browse data and find the blog post table. So these are the fields of the database table. You want to expand them a little bit to make them more visible and dates created, slug status of the post, so draft or published, and the author ID, which could be a number. So the first author that will be created has an idea of one and so on. So let us manually enter a new table row. Of course, as I told you, this should be entered through the admin interface. But for now, just for testing, we want to go to this button, press that, and that will insert a new table row. So the ID was automatically generated. So for the first row, it will be one. For the second, it will auto increment two. Two and so one. So let's put something for the title like dogs and content. Dogs Are Good. That's enough for now. Date created. This should be in format like 2022, 12 for the month, ten for the day of the month, slug. Like that. Dogs and jungle will take care of building the complete URL. So example.com, it will add a slash and then it will add the dog after the slash. Status, this was draft or published. So in here, you see we have zero or ones. So let's put one for published author ID, the first user of the database, we did create already a super user. So that user has the ID one. Right. Once you have done that, you want to go to write changes to the database file. All right, and then you can just close the database, and the row is there. Now, let's connect that slug that URL to our views block view. To do that, you need to go to your block folder and right click and go to New File and create a l dot py file URL. And in here, you want to import from the current location import views. So we are importing the views module. It's a file, but when you import things that is a module, it becomes a module. That's how we call it. Views now is available here, and we also need to import something else from Jango URL, a module, URL is another module of jangoimport path. And we need this path now, which is a function to create a URL URL patterns list. So I'm splitting that because this may contain different URL patterns. So the first pattern we are interested about is created through the path function. So what is the pattern? Well, it is slug, a column, and slug again, with this opening and closing bracket. So when the user visits a certain URL, let's say, let me write down something here. For example, example.com Slug, of course, they write like dogs, but dogs, we are telling Jango to look for dogs in the slug field. So jango will go to our table database table, and it will search in each row for dogs in each cell of slug, actually. So in each row of the slug field, it will search for dogs. And if it finds a row that has dogs, it's going to Execute block view, delete the parenthesis, Block Vew dot as view. So execute that class as a view. And there's also something else we need to give here, which we will use later. It's a name. Which is which should be a string, and let's say block view. This is a name we may need later, so it's a good idea to have it here now. So I hope you are following so far. We also need to do something else regarding URLs. You see that there is another URL that's PY file, but it is inside my site, which contains the configurations of the jungle project, not the jungo apps. So this file looks like this already. It's built by jango automatically, and here is this one here is also a URL patterns variable, just like this one in here, URL patterns, URL patterns. But this now wants to know about the URLs of the block app. So with each app you create, you want to declare the URL pattern in here. So after the comma, we create another list item, which is path this time, it has to be like this. So an empty string which denotes the home directory. So when the home directory is visited, and then something else after the slash is written by the user in the address bar of the browser, and something else is defined by the blogs. Blog is the name of the app. So block that folder name comes in here, URL. URL is the name of the URL PYfleO the block app. So blog dot URL. You could also write something else here. You could write myBlocks, for example, in that case, Jango would be expecting users. No example.com slash Dogs, but example.com slash myBlocksslash DOGS. But we don't want that, so let's keep it like that. Example.com slash DOG. Now we get this error. Include is not defined, and we need to input it from Jungle URLs import Path and include. Save. Also make sure to save all the files. So save this as well. Controls, save the views as well. So everything you see with that black.in Visual Studio code, that means it hasn't been saved yet. Now, let's see what errors we get type object block view has no attribute as view, see what's going on here. This happens in this file, so USPI block slash URL PY, which is here. So this class does not have that attribute. Let's take a look. This class, of course, it doesn't have that attribute. It only has model and template name attributes. No method called as view. That is because I forgot to inherit from a specialized view class which we need to import. From jango so from jangle dot Vs Import generic, and then from generic, we can access the detail view detail, not delete view detailed view class. So delete the parenthesis. So that means this class actually has an a view method inside. So you can right click and go to Definition. And of course, this does not have any methods here, but it inherits from some other methods. So if we go to base detail view, go to definition, this is also inheriting from these two. So maybe view has that a view function. Yeah, we found it. So that's the method. So there's a chain of inheritance, and we have access to that method now from our blog view class. Right. Save this file. And now it's time to try out our app and you want to go to this URL, So this is to be expected. So the homepage is not configured yet. We don't have any URL patterns that tell jangle what to do when people visit the homepage. So what you should look instead is one of your blocks. So currently we have dogs, the dogs slag. You remember that? I inserted it into the table, and we get this error. Template does not exist. An easy error to fix at dogs. So Jango recognized that we do have a dog entry in the database because if you tried it for cats, you'd get another error. So this time you'd get page not found, and Jango tried these patterns and didn't find any slug for cats. So dogs is a different thing, but the template is not found. So blog dot HTML. This usually is a problem with miscommunication with jangle. So Jango is not being able to find the path of block dot HTML. So let's check. Block dot HTML is correct here. So the view has the name correctly, and then let's look at the settings. Templates. The name is correct here. So this looks fine, but if you scroll up in here, you have the templates variable. And this now has some parameters about templates. And one of these parameters is DRS. So these are keys of that dictionary. Bend Derski. The DRski expects a value, and currently it's an empty list, but you need to declare here the list of template directories. So in this case, we only have one because you could have more, but we have one, so we have to declare that in the save and we get this other error template deer is not defined, of course, because we are using it in here before we defined it. So cut that from there and put it above its usage. So above this templates variable, out put it just here. Safe. And our server was interrupted, so we want to execute again. Python manage that PY Run server. Let's see what we get this time. Go to the browser. And whoop, we get the block. Dogs, Dogs are good and edit the name of the author. It's working fine. So that concludes this video. So let me wrap it up so you know where you stand so so far, we are able to address the user URL concerns. So when they enter example.com slash TOC, for example, this URL dot PY is being triggered and this deploys the views and the moduls. So it connects the two together to query data from the database. Those data are injected into these variables with curly brackets in the HTML template. And of course, then these are rendered in the browser for the user. And as you saw this time for now, I just entered some data manually using a third party program that accesses SQL three databases. But normally, as you see in the next videos, we want to get data through an admin interface. So this is what we're going to do next. We are going to create the admin interface and enter some data in there. So 212. Creating Admin Interface Views: Welcome back. Previously, we were able to build this web page with Jango and in this video, we are going to work on the admin interface. Specifically, we are going to add an option to be able to add blog posts from the admin interface. So for that, you need to have a user name and password. Remember, we created that previously, but if you miss that, you can go ahead and create that now with the command Python. Manage dot PY, create superuser. I did that already, so I'm not going to do that again. Therefore, I'm going to run the server and go to the admin interface and log in with my credentials. Now, you see that we only are able to create new users and new groups here, but not posts. So what we need to do is we need to go to the code and then go to blog, and then go to admin PY. So now we want to create a model. Here, we want to register our models, which is the post model in models PY. So this one here, we want to import that from Admin PY so from that models import post. Then we want to register that using admin that site that's register with small letters, and then here goes post. Without the parentheses, so don't call post, just declare it there. Save this file and go and check the admin interface. So refresh, and you should see posts here now. So if you click on AD, add the title. Let's say CATs Cats are also good. The slug could be CATs or wherever you like. Ardits the author and make it publish. So you see now, these are all the fields of models that's PY titled content slog, author and status. So draft or publish. Click on Save. Then go to the browser and go to CATS this time, and you see the new post is just here, as easy as that. Now, this is optional, but if you like, you can add some columns here to add some details about these posts. So the content creators will see this view when they create posts. So you should make their job easier so that they can find new blocks in this place here. First of all, what we want to do is see the name of each blog is post object one, post object two. That makes it very difficult to find other the post that you want for the content creator. So how can we display here the title instead of this unhelpful name? But first of all, where does this come from? What do you think post object? It seems to me that Post post is the name of the models class. So this actually is the name of that class. So Python, when you have a class and you just print it out, print out that class, Python will just print out the name of that class. I guess you know that. Let me show it to you what I mean. So let me open a Python shell, and you have a class. Let's also call this post. Just pass. So when you print post, you get this type of outputs or just say post, same thing. So Jango is trying to get a string representation of this class post. But we can change that by adding a magic method. Called STR. Actually, it's underscore, STR, underscore, underscore. So double leading and trailing underscores. With parenthesis, self comes as the first argument, column, and this should return now a better representation of this class, which would be self self represents a class itself, and title is attribute of the class. This title will be printed out when the pose is printed out. So if I save this I go to admin. Refresh. We get the titles of each of the blog posts, cats and dogs. Now, if you want to add some more content here on the side, what you'd want to do is you'd want to go to admin, and here you want to create a new class. Let's call this class post admin, which should inherit from admin Model Admin. So this is it doesn't need any arguments. Model admin is a type of class, just like we have models that model for normal class models. We have special admin models, so we inherit from that, and this expect now a list display variable if you want to pass that, which should be atuple with strings, and the strings should be the names of the model fields. So what do you want to show there on the side? Here. We have the title already, so let's show the dates created and the author. Yes. Let's do that. So date created. That's the name. Yes, dates created and author in Admint PY author. No. Okay, we did that, but this is just a class floating around. Jango doesn't know about this class. So we want to tell Jango somehow that Jango the project has to consider this class, so we need to register that class. That's what I'm trying to say. So post admin there, just the class. No need to call it like that. Make some space there for visibility and save and go here and reload. And this is the view that we get. So I know it's not ideal, but I'll fix it. The date when the post was created and author. So title disappeared because when you include this list display variable, then the admin interface will ignore the class name so it will not print out the class representation here, but it will print out whatever you declared here. Therefore, what you need to do is add title among these as the first one. So the order of the strings here is respected by jango. So now we get title, date created and author. If you are wondering why the date created for dogs is empty, well, that is because if you remember, I manually entered a RO for the dogs. Blog post, and obviously I didn't enter the correct date format manually. That is why Jango doesn't know what to display here. But when you create a post, the proper way through the admin interface, Jango is able to automatically generate the current date, that's it for this video. Next, let's take care about the homepage because currently it's not existent. Let's build the homepage in the next video. See here. 213. Creating the Homepage: Hi, welcome back. Previously, we created two blog posts, cats and dogs. However, our homepage is not working. So how do we add a homepage? Let's do that in this video. For now, we are going to keep things simple. We are going to have just a homepage that says this is a homepage. But later on we are going to generate automatically a list of blog posts in the homepage. For now, let's just have a simple HTML page so that you practice creating new pages in jungle. Oh, you know more or less how things work now, but let's repeat that. So where do we start? Do we start by creating a module or a view or an HTML template, so you may still be confused about where to start. But I would suggest you follow this approach. Always think about the user. So solve the problem starting from the user. What the user sees is the HTML. Then you go down in levels until you reach the back end, which is the models or the views. So let's start to build the page by thinking about the user. Therefore, you need to create an HTML template to show that to the user. So go to templates and right click over and go to Newfle and then usually the homepage is called index dot HTML. This is a standard way, but you can also write any other name that you like. So I'm going to keep index dot HTML. Again, the Tok then you have HTML tags and the body tags like that. Let's write some static text here. This is the homepage. But how can the user get this HML template? What do they do? Well, they enter a URL right in their browser. I mean, they could also find that URL on Google or directly enter that on their browser. It doesn't matter for us, but they have to enter a URL somehow on their browser, which would be like example.com. That is a homepage. So we need to go to the URLs of our blog app. So this URL, that's PYFle not the URL, that's PY fle off my site. We are done with that. We entered. We told Jango about the URL, that's PYil of our app, and that's all. We close that now and we work on the app URL. So the blog URL, which has this list of Path function calls. So this function is being called with two arguments, one here, one here, three, actually, and a third one in here. So now we need to add another call. Path. This time is just an empty string. Before, after the domain name, we had the slug. But now after the domain name, we don't have anything. So just leave it an empty string there. A comma. Oh, now we have views. Okay? So we're moving into our roadmap of having a page published. So views, we want to create another view now in views PY. So let's just write it first here. We are going to name it home view. So homeview dots view will be the method of that. So we have to call aview. Let's give it a name, so we maybe use it later. Home underscore view, a string, right? And then create a view. So a new class. Class home view comes from generic detail view. Actually, it shouldn't come from this, but let's leave it like that for now. And the model now. Well, this page doesn't really have a model. It doesn't need a model actually, because see, this is just a static page. It's not getting data from a database like block dot HTML. You see, in blog HML, we get this data from the database. This is not the case here, so you can have views without models. So all you want to do here is template name equal to home, sorry index dot HTML. So that's one which means that when users visit this URL, this view will call that template to be rendered in the browser in the user's browser. That's it. Make sure to save, use that PY, make sure to save URL PY, make sure to save index dot HTML. And then try out the page. So this is the homepage, and it seems to have a problem. So problems are now emerging. It says that home view is missing a query set. So you need to define the home view model. The problem here is that in views, this is not the correct view type to use with views that simply render a template without getting data from a model. Therefore, in this case, what you want to use instead is a template view. Save and refresh. And this is the homepage. It's working. You can see it as I zoom it in. Right. So that is how you can add more pages. And you can also now understand the difference between different view types. So detail view and template view. Template view means when you only need to render a template without getting data from my model, and this is a more complex view which gets data from models and passes them to templates. In the next video, I'm going to show you how to use yet another view type, which is basically used to create a list of objects, a list of blog posts in our case. Talk to you in the next video. 214. Creating the About Page: Previously, we built a homepage for our app. Now we want to develop that homepage and show the list of blog posts on the homepage instead of some static information. So before we use detailed view for blog pages, template view for the index page, now we want to use another type of view to show a list of blogs. Template view is not the best choice for this. Therefore, we can delete this or we can keep it and use it for about us page. Let's say, our website should have an about us page where you can write some information about the company or yourself. So let's see how we can change that. Let's start from the index, the HML page and rename it to about then in views, we want to rename index to about to reflect the name of the HTML template, and also home view maybe change to about view and then go to l dot py and change home view to about view delete those parentheses and home view about view. And now we want to give another URL pattern to that about us page. We should be about slash like that. Save URL that's PY, save views that's PY, and that's all around the server. Oh, I'm not in a virtual environment, so close the terminal and open a new one and then upper arrow key to execute that server again. So the homepage now is not valid anymore, but about ending with a slash is valid. So it should end with a slash. Otherwise, you get an error. But this page is valid now. So this page, let's say this is the about page. Right, save that, refresh, and we see the change. So that's about adding yet another page. In the next video, let's go ahead and make the index dot HML page again with new contents. So showing a list of blogs to you. 215. Listing Blog Posts on the Homepage: Hi. In this video, we are going to add the homepage and show a list of blog posts in that homepage. So let's start again from the user's point of view. So we want to have for the user an index that HTML template with a doctype HTML tags and body tags. Then what do we put in here? Well, so tags with curly brackets and percentage symbols, and then this time, what we do is a four loop, four post in post list. And then we do something here, and then we end that loop and four inside here, we do something else. I'll explain you what post list is and what post is also. But basically, then we have the variables here, which could be post title and post content. And maybe No, post content would be too much to show, but we could say author. So this will be just a list of blocks. We don't want to show the content in that list because it would be too much. So post title post author. Now, what is post list? Post list is a view, which we need to define in views that PY. So yet another view class. Class post list, the name has to be in the same format, so to say, as this one in here. We used post underscore list in here with lowercase letters. Now we need to use post in camel case lists of P and L are uppercase. That inherits from generic dot List view. So this is yet another type of view. We had detailed view to render HTML templates that get data from a module. We had a template view to render HTML templates without data from a model, and we have this list view, which is specialized in rendering multiple data rows, in this case, multiple posts. Now, this type of class expects a query set variable, which should be equal to Post. Post is the model. So be careful here. It's not the view. It's not blog view. It's not about view, of course, it's the model of blogs, which you can find inside models at PY. So post that model is the one we refer here. What we're trying to do here is we're trying to query the objects. So the rows of that post module. Without the parenthesis, we want to apply a filter and maybe get all the objects, maybe apply a filter such as status equal to one, which stands for. Let me show it to you. So status, we're talking about this field. So we want those posts, those blog posts, which have a value of one for status. Status has either zeros or ones. So one stands for publish, zero stands for draft. So we want to show there only those posts which are published a status value of one. And perhaps you want to order them by what field? So we have date created, perhaps. So date created. So that is the relationship with the moduls and the relationship with the templates now is templates. Name Eagle two index dot HTML, right? So we built the template, which looks like this. We built the view, but we need to do something with the URL also. So we have one item here, two items here. We need a comma here and add a third item, which is the homepage. So an empty string. And we want to get from views we want to get but the post list view, post list. Post list is a class, so we want to get it as a view. So call the method as view from post list and give it a name such as whom? Now I think we are ready to try out the browser and go and visit the homepage. But first, make sure you save everything. This one, the URL that PYfle, the index that HTML file, and the views that PYfile. Save those and see if the app is running, it's running. So visit the homepage and it's working. So dogs, did, cats, did. Yes, these are the two blog posts. Not very appealing, but you can change that with some HTML. For example, you may want to put the title inside H two tags here. And the author, perhaps in P tags. So in here. Say reloads and it looks a bit better. Now the ordering of this is that the older posts are on top and the newer posts are at the end. So if you want to change that, it's very easy to do. Just go over to views that PY and you want to change the query set, the order by by just adding a minus so this is the jango syntax, and then refresh, and Kats will be on top now, the newest block post. So this is looking good, but I think there are two things missing in here. One is that each of these should have a link that the user can click and go to that particular block post. And second, what is missing here is some styling. So this looks pretty awful. We need to apply some styling, and we're going to use bootstrap for that. Which is a CSS library, and it just makes things. So web pages look much better. So next, we're going to add a URL here, which has to do with URL tags, so you're going to learn how to use URL tags, and then next we add some bootstrap styling. See you. 216. Adding Bootstrap to Django: Hi, welcome back. In this video, you are going to learn how to go from this to this. So we are going to add some CSS styling using the bootstrap library, which is a CSS library. Bootstrap makes it easy to stylize your HTML documents, and nowadays, it is a must to have a modern looking website. So let's go where we left it with our code. This is the index that HTML document which renders this webpage, and this is a document we are going to work with in this lecture. The way we are going to do this is by looking at the bootstrap documentation. So try to Google bootstrap, and the first result should be the bootstrap official webpage. So a few words about bootstrap. You know, CSS is something that usually is placed somewhere in a folder which you will name static. So you create a folder in the project directory in the root directory, and you name it static. And inside the static, usually you create a file such as main dot CSS. And in that file, you write some CSS code. That CSS code, basically, it looks like this. Let's say P and then you have some curly brackets like that, and then you say color blue, for example, and then font size 17 pixels. That would be CSS. Of course, it would be placed inside a CSS file as I said. Although there's also a way to just put this code, integrate it into the HTML document. Either way, it does the same thing. What it does is that this code, for example, we get all the P tags and it color them in blue in blue. So the text will be blue and the font size of the text will be 17 pixels, and so on, you have other properties like that. Now, when we use bootstrap, what we're doing is we are using code that is already written. So I'm talking about CSS code again. So the library has CSS code, and then you just use that code by just referring to something called a class. For example, if you wanted to use and we will use bootstrap, instead of doing that, you'd say class equal to P pretty. For example, let's say that this paragraph, this code also would have something a name somewhere. So let's say P pretty. So this is what would be inside those bootstrap files that we install. And then in our code, we just have to refer to that class of bootstrap to apply those attributes to this paragraph, which in this case, would be the author name. So you will see it in action. Let me delete that and that as well. Right. And let's go back to the bootstrap website. So there are two ways to include bootstrap in your project, either to install it or you can use this quicker way with JS deliver. And here you have the guide how to include bootstrap. So we have to include the CSS file, which, as I told you, contains all that CSS code. So we should copy paste this code here. I can just press copy here to get that code. And place it inside the head tags before all the other style sheets. So head tags, we don't have any head tags here, but we can create them. Head, like that. So between here, we paste that link, with a tag link tags, opening there, closing here. Then we also need to place the JavaScript file. So dot JS, you can see. And to do that, you need to copy this again. So under Bundle, there are several options, but bundle is the best one. So copy. And you need to place that. So place one of the following scripts near the end of your pages right before the closing body tag, right before the closing body tag. So just here. And that's it. Now, save this index that HML file, make sure the app is running and visit it, and you will see a difference in the phones already. So the links are a bit lighter blue, and the font is bigger. And so that was how to include bootstrap in your app. Now, let's follow the tutorial again. So here we have a starter template. So it starts with this doc type HTML tag here, HML Lang declaration and head tags. So I'm going to copy this and replace that with that one. So the first HML tag, then we have the, that and that meta tags. We already included this link, so we only need these two meta tags. Under the head tag, under the head tag here. So meta meta, the link to the bootstrap CSS files. And the title, this is optional. So it's not related to bootstrap, but we can also put a title let's call this block posts. The title tags are also inside the head tags. The head tags closes here and here, then we have the body tags. Hello world, that's optional. Here we have the script that we already included, this one in here, so everything is okay. Right. So down here then it explains what all these tags do if you want to read that. What I want to do now is use bootstrap. So these are the requirements, the links that we put in the meta tags, but now we want to use the actual features of bootstrap. So the actual library. What I'm going to do is usually with bootstrap, what you do is you have a main DIV tag. Which starts in there and it ends where your content ends. So down here and I'm going to align the div. So opening div, closing div with a slash div and the brackets. So this is all our content, right, which is reflected to that from cat to the last died here. And this div now should have a class equal to double quotes. And inside those quotes, you write container. This is one of the main classes of bootstrap, and you see that I save the page, the documents here and refresh the page and we see a difference already. What bootstrap is doing with this container is that this container is some CSS code saved somewhere in this CSS file, and this container basically has some margin, some spacing between the text and area here. So the page is also already responsive. So if you see it, it moves, it adjusts the width of the browser. So next, what I want to do now is that for each of the posts, so the posts are cats dit, so this is one post with a link at the author name, this is another post. So for each of those posts, I want to create another division. So from there until before the end four, so here and maybe it's a good idea to indent this, select them like that on tap to indent them. So basically, these two are part of this div element. So this is one element now. So what I'm going to do is I'm going to assign a class of card. So where am I getting this? Well, in bootstrap, for example, you can see if you go to layout, how you organize your HML documents, you see you have containers, and you see you have the container class here that we already used. Then if you go to components and you go to card, You'll see that you can organize your content in these sort of cards. So all these elements here is a card. You see class card, and this is what I'm also doing here. So I'm putting a post inside the card. So if I save that now, refresh, you see there is some sort of border around each post. And we can make that better by also assigning. After a space here, we do three, which stands for imagine around each of these two boxes. So imagine of 33 now is a unit of CSS or more to say, a level of spacing. And so you can read about margins should be under utilities. This is about spacing, so spacing, you will see, for example, M stands for margin, and then you have the levels. So one, two, three, four, five, so that's about making some space. Now, let's go back to the card example in here. So then we have this image. We don't need images now. So this image here, we don't need that. But then we have the card body. So there's another div inside that card class div. So Div and we get that and we place it in here. So like that, in dent again, these two. So now, this is class equal to card body. And then we also have something else card title. So this is a title of the card, which in our case, it would be cats and dogs, which means that we could add a title here. So see what I'm going to do Div like that. So this would be class equal to card title. And inside, we would put post that title. I know I'm duplicating this, but I'll tell you why. So post that title and refresh. So, yeah, we have cats here, dogs here. But it's better to use maybe H two instead of DIV. So H two there, and don't forget to change this also to H two. It opens here, it closes in here. So I refresh and this is a title, this is a title. After the title, we would have maybe the text. So this text here, which gets card text. A div. And this would be post dot content, right. So that's our text. We want to display some text below the title. And this, as I said, is class equal to card text. Save refresh to see the changes. Yeah, so the content is also here. Now, next, I want to remove this link by changing that to a button. So you see that here we have this bottom. So that is an A tag and this class. So what can we do this? Let's assign a class of it was BTN and then BTN primary. Now, let's save this and refresh to see cats cats are good too and the button. Now, since this is a button, we don't want to display the title here of the post anymore. We want to display something like read more. Safe, refresh. Yeah, looks better. Perhaps we want to add under the content div. Perhaps we want to have another div where we say author is post that author, right? That one. And we remove the P text now since we don't want two author fields. So remove that. And this would be also card class equal to card text. Safe. See the changes. Yeah, cats, cats are good to author dits and read more. Now, you see that these divs are a bit too close to each other. So the content div, the author dif, the button div as well. If you want to change that, you could change divs to paragraphs. So P instead of DF P, P, P here as well. Safe refresh, and it looks a bit better now. The buttons look a bit big to me. That is because this text here is an H two element. So if you want the text to be smaller, you want to remove the H two tags, the opening tag and the closing tag. Safe refresh, and it looks better. The page is also responsive so you can shrink the browser. That's about this video. In the next one, I'm going to introduce you to jangle template tags. You will learn in the next video what they are about. See you there. 217. Template inheritance: Hello. So far, with our website, we have built this homepage. You can see it's in the homepage, and we also have the About page as well. So slash AboutSlash This is the About page, which doesn't have any bootstrap styling, of course, because we apply the styling only to the index that HTML template. And we also have the blog dot HTML templates as well, which is one of these pages or cats or dogs. So three templates, one, two, three. Now, we need to find a way to navigate through the website, which is that, for example, how do you go, how can the visitor go from this page to the about page? Well, usually this is implemented through a navigation menu bar, which could be somewhere on top here. And you could click about Link and go to that page. This is what we will do in these videos now. How can we implement that? Because the navigation menu bar should be in every page. So one way to do that is to create that navigation menu, which is created with HTML. One way is to code the HTML for that navigation menu in each of these HTML pages. But that is, of course, against the dry principles, dry which stands for, don't repeat yourself. Therefore, what we're going to do is we are going to use template inheritance. What is template inheritance? Well, it works like this. The component that will be repetitive. So the navigation menu bar in our case, is going to stay in one single file. And then the other files, which is about blog and index, these files will get that other file where the navigation menu is. And this is referred to as template inheritance. So let's see it in action how it works. So right you click over templates and go to New File and write something like base dot HTML. Base HML is going to contain the navigation menu bar. Now, to create a navigation menu, in HTML, you use the Nav tag. So open it and close it, and then inside, you have another div open and close it. And inside this div, we have the UL, which creates a list of menu items. So the first menu item would be with L I Right. And then we have another one. So home, we have about us. Yeah, that's all. So the first menu item, the second menu item. So this would be for whom. Therefore, inside the first LI tag, which sends for list, we place we put a tags, which will create a link. Same for the next one here, a tags, right? Inside the first a tag. So just here, we say HRF, this property, which is going to have as value inside quotes the URL to the first page, which would be this tag. URL. Single code. Well, now we need to look at blog URL and get the name of the URL for the home page, which is home. So that goes in here, home. We do the same for so about view. Again here, let's copy that and paste it inside the first H tag. Careful. There's a space here, Hf about underscore view. Now we need to do something else. We have to go to index dot HTML and cut from the opening body tag in here until the very first line, cut them out and paste them on top here. Make some space, paste them in there. A go again to index that HTML and cut again, starting from the closing HTML tag, including the closing body tag, including the script tag of bootstrap. Cut them, go to base that HML, go to the very end. Make some space, paste it. Now base dot HTML will be the parent. So we talked about template inheritance. This is the parent now and index that HML is the child, which is going to get this from base dot HTML. Actually, every page, not only index, but about HTML, block dot HTML. So all the blog posts will get all these from base HML. That allows us also to apply bootstrap on every single webpage. And now you need to tell each of your pages, such as index that HML, you need to tell it that it has to extend, so through a template tag like this, you say, extend single quotes base dot HTML. So copy that and paste it in about HTML as well. And here also, we need to delete those body tags on that as well and just say that and go to block dot HTML. Also, delete body tag, HTML tags, doc type tags, paste that, delete the closing HTML tag and closing body tag delete save, save. Then go to base dot HTML and at the end, so after the navigation menu me, we want to do a template tag again and say block content. And also the same thing. So a template tag and block content. So what is this? Well, basically, H webpage. So think of what the visitor sees on the website. They see on top a navigation menu bar, which is this one in here, right? And then they see the content which could be the post about cats, the cats content, or in the case of about it's the contents of the A page. So under the menu comes the content. So this is the content. And now we need to remember this variable content and go, for example, to index that HTML, and then under this, we say Block content. And it ends again with block content. Like that, which means that as you see this extends base dot HTML, so it gets the data from base HML, and then this thing between the block, the content tags from there to there is somehow combined with that base HML page to be rendered in the browser as a complete page. And that's about template inheritance. It's a bit difficult to grasp. So let's see if we did some errors now. We're going to see the result Yes, of course. So it says that extend, did you forget to register or load this tag? Well, extend that is because jangos not recognized in this because it extends. So blog dot HTML extends, base dot HTML. Let's do the same for the other pages and save this one as well, and save. Yes. This is a base dot HML template. Let's look for the next error. Okay, not bad. So we see something here, but we don't see any text. So let's go back and fix that. I base dot HTML. So here we have the link. But we don't have any text. So let's say home for that and about us for this. So if refresh. And yeah, we see something now, press on about us. It takes us to the About page. Go to home. It goes to home about us. Great. We don't see the contents here, so let's fix that for the At HML page. Because we don't see it because we don't have those block content tags. So block content here and here, but this one should be with block, safe, very fresh, and this is the content of a boat. Now, of course, if you want this to be prettier, you have to put it inside div tag and say class container, safe, refresh, and now it goes somewhere in the middle. And you can also make it even better. So this is a main diff that contains everything This would be something like H two. And then we could add more diffs with content. This is the content like this. So the navigation menu now, it doesn't look very pretty because we haven't applied any bootstrap classes styling to this element. So you have NAF with no class, D with no class, UL, LI and A, also, no classes, no bootstrap styling. So let's do that in the next video. See you there. 218. Applying Bootstrap Styling to the Navigation Menu: We'll come back. Let's add some styling to the navigation menu now. So we go back to base dot HTML. And the first item is NOV. First of all, we want to select all these and indent them one and two. So it should be indented under the body tag. Right? So start with NAV and class equal to I know some classes from Bootstrap, and you can also find examples online. So Nov bar, it specifies that this is a Nov bar. So use the Navbar style Nov bar light for the color and the background BG light as well, have some shadow and then you also need to give class is one property of NOV and also after the coat, here you need to give another ID equal to main NOV like that. So this is used by JavaScript of bootstrap. Then the next div will have a class of collapse Nova collapse. So these are different classes and an idea of Nov boar responsive. Then we have the UL class. Nvbnuvt. ML stands for margin left and its value will be two. Lastly, the LI class is NOV item. So this is an item of the menu, and that's it. Save that and see what will change. Okay. Not bad. Now, the A tags, so the links don't look very nice, but the bar itself looks good with a shadow. So let's do the styling of A tags. So a class equal to Navbar brand, safe. Reload. Home looks good, but about us not doesn't. So let's do the same for The other one like that. Yeah, it looks good. We need to put it a bit to the right. And a P three class added to the first A tag should work. So save, refresh, and it goes more to the right. So P three means that give it a padding around that A class, and you should do the same for the other ones. So P three, save, refresh. That is the navigation menu. Now, down here, we want more space between the navigation menu and this content. Let's fix that. I think that would work by adding the navigation element to the class of the navigation element. We could add an MB of three. So B stands for margin bottom. Refresh. And yeah, now it's better. So there is some space now under the menu, the navigation menu bar. And that's about it. I hope this makes sense, and I'll tex to you later. Thanks. 219. Demo of the Django Translation App: Hi, welcome back to another series of videos. In the series, we are going to build a translator web app with jango. So this web app, Jango app is going to be part of our jango website project. The website has already a block app which we can access through the home page. So this is just a sketch of the website. And we also had this about us page, which is also part of that block app. No, translator is going to be a second app that we're going to add to this jango website. And there are three reasons I'm including this translator app in our jangoPject. The first reason is to rewind what you learned so far. So you learn how to create this block app. But now I want to go through the app creation process once more because we created an app already, but when you create another app, you see things from a different perspective, and you learn better, I'm sure. So that's one reason to revise the app creation process. The second reason then is to learn about jango forms because in this jango app, we're going to have two text boxes. In one, the user is going to enter the term, the sentences, they want to be translated. And in the second, they are going to see the translated text. So we're going to use English as a first language, and then another language as the translated language. We're going to talk about that detail later on. So the idea here is that you're going to learn about forms. In jango because this thing here is actually a form. So a form that allows users to enter some data, some text, and then they perform a request, which is a post request. So they post some data to the server. In this case, it will be the text they will write in here. So the server, Jango is going to get this text and use a Python library to translate that text into another language. Then Jango is going to send the data back to the user. So this here will be the input box of the form, and this will be the output box of the form. So again, revising the app creation process was one reason and learning about forms is another reason. And the third reason I want to have these videos is to show you how to process content that the user sends to our jangle app. Um, so in this case, will be the text, and you're going to see how to organize the library that processes this text in files and how to get this text and how to send it to the user because with our block app, we are not really processing any user content, but this time we will. So get ready, and I'll talk to you in the next videos. It's here. 220. The Step of the Django App Development: Hey. In this video, I'm going to mention the steps that you should take to build this particular translator app. And these steps also stand for any other apps that you want to build. So first of all, what you want to do when you have an idea or some requirements to build an app, you want to find out if it is possible to build that particular web app. For example, we want to build this app which translates, let's say, from English to German. So first of all, you want to answer the question of, is it possible to translate a piece of text, so I string, which is in English. Can you translate it to a German text? So I string again, but the German version of that original string. So can you translate text with Python? And for that, you would want to do some research on the web and maybe OscOFms until you find a Python package, perhaps, which would make it easy to do this. Or you could also build your own package, which should be a lot of work for this particular task because translating languages is not easy. So I did some research on Google, and I found out that a good package library to use for this is Google Trans, which is basically built on top of the Google Translate API. So with Google Trans, you can provide a string and Google Trans will get the translation from Google Translate, and it will return a string in the target language. So problem solved. It is possible to translate via Python. So we have the green light to continue creating our app. Then the next thing you want to do is to create an empty jango app which we're going to do in the next video. And then after that, you want to follow the top bottom approach, which is to think from the user viewpoint. So instead of going through your modules, creating a model or maybe creating a view, you want to create what the user wants to see, which is the HTML template. So the first step would be to create an HTML template, and then that template, that HTML has to be rendered to a particular URL. So next, you want to configure the URL of your app, and then after that, you want to connect the URLs and that URL wants to trigger a particular view. And so next, you want to create a view. The view will basically get the HMLU created in this step and serve it to that URL. Then you want to create a model which contains the data that will be injected to the HDML template. And at this step, then we should have built the structure of our web app with HTML already and with the text box is ready for text. Then we can get that text so we can get that text and translate it and return it to one of the text boxes. So those are the steps that we will take. So in the next video, we are going to create the jango web app in our existing jangoPject. I'll talk to you in the next video. 221. Creating an Empty App Structure for the Translator App: Hey. In this video, we are going to create a new app in our existing janga project. First, let's have a look how the website looks like. So in my terminal, make sure your virtual environment is activated. Mine is not because I don't have this parenthesis in front here. But if I create a new terminal, using the plus icon or go to eminalNw My virtual environment is activated now, so I can go ahead and say Python, manage that PY run server. Go to that website, and this is how the website looks like now, and we're going to have another menu item here, which is going to contain the translator app. So let's get to work. Let's create the app, stop the server from running with Control C and Run Python, manage dot PY, start app, and then give a name to the app. Such as translator, execute and a new translator directory is created. You can see it in here. So it's in the same directory with block. Block is in the root directory. Translator is also in the root directory, as you can see here. Now, once you create an app with Start app, then you want to register that app in my site settings. Go to settings dot PY JangoPject settings and you want to go to Installed apps. So before we added block here when we created the blog app, now after the comma, we want to add another item to this installed app list. So it's string, and the name of this is or Translator, yeah. So this should reflect the name of your app and the name of the directory here. Save settings that PY. And that is how to create a new empty app in jungo. In the next video, we are going to start building our HTML template. So see you there. 222. Creating a Django Form: Previously, we created a new empty app in our jangle project. Now the next step is to. So this step is completed. Create empty jangle app. The next one is to create HTML. So as we said, what we want to have is we want to have a new menu item here, which we're going to create later the item, but first we want to create the page. Then we add that page to the menu bar. So the page is going to be simple. It's going to have one textbox in here and another textbox on the right, and a button somewhere below. So the user is expected to enter some text in English, and then when they press the button, that text is going to be translated to, let's say, German. So we're going to pick German as our example. Of course, you can improve the app later on by adding an option to choose other languages as well. But for now, we're going to keep it simple to focus on forms. That will be a form that we'll be building. Let us start by creating an HTML file under templates. So right click over Templates and go to file. So new file. Perhaps translator dot HTML would be a good filename. Now we want to build those two textboxes and the button. But instead of typing the HTML here as you watch the video, I'm just going to copy the code that I built already and paste it in here and explain it to you. Now, to make it look good, I will also paste the link to the bootstrap. Source so that the text boxes look nice. And you can find this code attached to this lecture. So I'll save it, and then I'll right click here and go to Reveal in Finder or in Windows Explorer, and then I can double click it. And this is how it looks. So we have these two text boxes which can be expanded by the user, the user can type text in here, can also type text in here. But this one here will basically serve to show the output. But anyway, the user can also type in text in there and modify the output if they want and so on. And the submit button is what translates this text to that one. So now, of course, it's not working. Don't expect this button to do anything because it's not connected to jango. Let me explain you what the code does. So this link here is just temporarily in this file because normally we don't need that. So I'm going to delete it. We don't need it because that link is already in base dot HTML. So this one in here. And that bootstrap styling will be applied to all the templates that are extending base dot HTML. Currently, though, translator HML is not extending that template. So let's add the tag that extends, so it extends in quotes base dot HTML. And then we also want to do the text again and say block content. There and close it in here and block content. Just like that. So this file is going to get the code of base dot ML, and this code will be combined with that code to serve the complete page, including the navigation bar. So the menu items on the webpage. So this is what we have here. We have this class container, which is the main div that contains everything, so it starts in here and it closes in here. And inside, this div contains a form. So the form starts in here and it ends in here. So the form is this including both the text boxes and the button. So this one here is a row. It starts in here. It ends in here. So basically, this row here, it's a division that contains all these two boxes and the button again. And inside that division with class row, we have this division also, which is the first text area. So this call SM six defines that this is actually a column of that row of that row. So this is the first column which corresponds to this textbox, this column here. And then the next column, which is this one here, contains the other text box and the button. So text area means this text box here, and input with class BTN means this button here. So text area, the first text area, text area, the second text area, and input the button. That's it. So again, the form now, you see it has an action property, which has this template tag that I have written here. And so what's going on here is that when the button is pressed, so this submit button is pressed, something is going to happen. And what happens is that this URL will be visited. This is not a URL. It's a name of a URL pattern that we will create later on. You'll see how that works. And the method is a post method, which means that the user is sending some data and they expect to get back some data process from the server. The rest we explained already. So the divisions and the text area with this class bootstrap class. Rows means that it has three rows of text by default, so one, two, and three rows of text. So the height of that text area. This name is going to be used later to refer to that text area from jango to get the text of that text area and process that in jungle so we have the other text area and inputs button with this class from bootstrap, the type is submits, which means that when that button is pressed, this form, the form will be sent. So we'll send the data, the original text of the user in this case, and value is the name of the button. So submit, submit. And that's it. All right. So we have HTML, but we need to define a URL through which the user will access this particular HTML web page. So let's configure the URLs in the next video, too. 223. Getting and Processing User Input Through a Form: Hi, welcome back. Previously, we built this web page, which looks good, but it's not doing much for now. So whatever text you enter there, you press submit and nothing happens. So the text disappears. So let's implement this. But first, you need to understand the two HTTP requests that are taking place here. The first HTP request is when the user enters the URL, let's say example.com slash translate Slash or this IP of the local host as it is in this case, and this is a get request. And this request is being handled by this URL pattern, and of course, also this one. So both these two are merged into one URL, which is example.com slash translate slash. But there is also another request being made, and that is when the user presses the button submit. Another URL is being accessed, and that is the one that you see in translator dot HTML at this line in this line here. So you see that when the button is pressed, this URL is visited. So translator view, which again, is the same URL so translate review, which corresponds to example.com slash translatAS, right? So, currently, visiting the URL through a GT request like this when you just refresh your browser or enter the URL, and pressing the submin button is taking the user to the same URL. We need to change that. We need to separate the two requests and perform different actions depending on whether the user is doing a get request or a post request. When the user makes a post request, we want to get the text from here and display the capitalized version in this other box. So let's do that. What we need to do is we need to distinguish in views. We need to distinguish if request dot method is a post request. If that is the case, we want to get the original text or the input text that the user enters in here. And the way we get it is through the request object dot post and here, what comes in here? Well, here we should enter the name of that text area, which is in my case, my text area. So here, my text area goes inside as a string. So if that is the case, do this else return the page as it is. So else means if the request is a get request. So if it's a post request through the button, we get the original text from the text area, and let's print it out just to see how it looks like original text. Else, in the case of get request, we just return the page as it is. So translator dot HTML. Save. And let's see reload first. And we get this error. It has no attribute method, because it should be method. Sorry. Save and visit again. Translate is our UL Translate. And let's write something, submit. And let's see what we get now in the terminal. So I see AAAA is printed out, right? This line was executed. But after that, we got an error. It says that the translator views translator view. So this view, this view function didn't return an HTTP object, which is true. So we got a post request when we pressed the submit button, but there was nothing returned here. So we should return something. And this is also a render function call, which gets a request as argument translate the HTML. And now, we also need to pass something else here, which is the output. So far, we saw that this works. We are getting the texts of the user successfully, but we want to do something with that text. For example, let's say output, you go to original text. For now, as we said, let's say we turn it into uppercase. Then what we pass here in the render function is a dictionary, which is like this. Let's say output, text. So this is a key, a string, and it has as a value output. So this variable, the uppercase text. Now, we save this and then we go to translator dot HTML. And in this second text area, in between the first text area attack and the closing text area attack, here we put a template variable, which is out put text. So this thing in here. So the value of this actually, this will be injected into this text area. Let's see if this is going to work. So make a Get request. We get the web page successfully, write something, submit, and we get the capitalized version of that text. So it's working. So that capitalized version of the text came from this output text. And that is how to use HTML forms with Jango. Now, before we close this video, I want to show you an issue with our app So as you can see, you write some text here, submit, but the original text disappears after the user submits the text. So let's fix that. It's very easy to do. First, let's understand why that is happening. So if you go to Views, again, we have I request equals to post, and in that case, we send the output back to the page, but we don't send anything else. So this will be a new rendering. It will render the text boxes, the two text areas of translator HML, but one of them will remain empty because this will be a refresh of the page, so to say. Therefore, if you want to also have the original text in the webpage, what you need to do is add a new pair here in the dictionary. Let's say this would be original text. As a string. So the key and the value of that would be original text, the variable. So this one in here. Copy that string and go to translator dot HTML. And here, in the first text area, we place a template variable. Inside that goes original text. So just like this textbox, we have that one as well. And as easy as that, save at translated HTML, save views H dot PY as well, and the server restarted. So now the server restarted. So we know that changes are applied now, refresh the page, write something here, submit, and both the original text and the output text remain on the webpage. That completes the jango part. So we have a working web app. And now all we need to do is instead of capitalizing the text with upper, we translate it with some other package. In this case, we're going to use the Google Trans package. So let's do that in the next video. Thanks for following so far. See you there. 224. Completing the Translator App: Welcome back, and let's go with the final push of our app. Currently, this app returns the capitalized version of a text. Now let's translate whatever text the user enters here. To do that, we're going to open a new terminal to install Google Trans. But currently, however, there is an issue with this library, which can be fixed by installing an Alpha version of the library, which you can install the Alpha version using what I'm typing now. So you could try don't be afraid to try either of these. So either Google Trans or whatever works. So if you install one and you try it out, it doesn't work, then install the Alpha version, and that Alpha version will override the previous version that you installed. So no harm made. Whatever works, use that. For me, I found out that this version works. So 4.0 0.0 dash R C one execute. And yeah, it was installed. Then I can try to use it. So I am I installed it for my virtual environment. So be careful with that. You see NFR. It was activated when I installed it with PIP. So now I can try that out. I can open a Python Shell. And the way this works is that you import from Google Import the translator class. Then you create a translation instance. Using that translator class and then out of that instance, you say translation that translate text equal to. Let's say, how did you learn Python in quotes? So it comes as a string and test for the destination language. Let's say DE for German, you can find these abbreviations on Google, so language abbreviations. D stands for German. And if you access text out of that you get the version in German of that term that sentence. So the library is working for me. Now I want to write this code somewhere in my jangle app in the translator app. So in such cases, what you want to do is you want to create a separate file inside the translator app, call it maybe translate that PY. Inside here, you want to import from Google Import, translator. What we want to do is maybe create a function, translate, which gets a text as parameter. This function will be used inside views PY. We're going to call that function here, which will be something like this. From dot Import, translate. Then the output this time will be translate dot translate. The text will be original text. So translate is this function. So translate is a module name, so translate dot PY and translate is a function. So text, then, let's say translator, equal to translator, the instance, then translation equal to translator dot translate text equals to text, destination equals to the string DE, and then return translation dot text. This is a translation object, and you need to extract the text property out of that to get the actual string. Save that and save this as well. And let's try the app. And it's working. So we got the translation in German, as you can see. Right. Lastly, I wanted to also add a menu item here for our translator now so that we can easily access it. To do that, you want to go to Base HTML, and just copy one of these, one tax, copy it and paste it down here. And so this is going to be translator. And this is the name of the URL which you can get from here, URL's PY, copy that, go to base that HTML, paste it in there, save and here is the item. So this is the website. That concludes this jangle project. I hope you learned from this, and I believe this should be enough to get you started with jango. So we covered some of the very important functionalities of jango which was handling databases and getting user input from the forms and processing that input and then returning output to the user. So thanks a lot for following and see you again. Bye. 225. Demo of App 10: Geocoder Web App +: Great. As you may know, we are approaching the end of the course, and this one, this is the last section of the course where you build your tenth application. This particular one is special. The special thing is not about the application itself because every application is actually special. The special thing about this application is that you'll build this one independently. So this is in the form of a project. You have to build this from scratch. And you have learned all the skills throughout the course, so the skills that are required to build this particular application. And in this video, what I wanted to do is I want to give you a demonstration of what this application does, and then you can start building it right away after this video. Then in the next video, I'll show you the solution. So I'll show you the code on the video and explain what the code does and also the approach that I used to build the application. But no, I could have recorded these videos just as I did with the other nine applications in the course, but I really wanted you to do something on your own, and that will serve you for two things. One is that you'll actually do something independently, and you'll learn a lot from that. And the second, you can use this as a portfolio. This is quite a nice web application. But this is tough. I mean, I would be surprised to see anyone making this work 100% unless you're a genius. I really mean that. But you should be able to make this work, let's say, at around 50%. If you make it work 50%, then you have really learned from the course. So what I mean by 50%? Well, you may stop somewhere and ask for help. Maybe you have an error there and you're not being able to understand it and solve it for going forward, or you just don't know what to do next. So in such scenarios, you can step in and post a question in the Q&A area. So in the discussion area of the course. I'll say don't ask me right away. I mean, I like questions, but it's good for you to solve the problems yourself. You know, programming is hard. I mean, often, all you need is a break, like a coffee or tea to just refresh your brain and make it think better. And then you suddenly may find yourself cracking that problem. But if that doesn't work, then I'm here to help you. Just drop a question, and I respond within a day. And my recommendation now try to start from scratch. Don't look right away at the code or the lectures that we have gone through in the course. Instead of doing that, try to gather your thoughts in a sheet of paper. Write down some steps such as step one, make the user interface, step two, bit of script that sits with data and generates an output, and then make the flask, structure, and so on. And then you go and implement these step by step. If you stock then, it's perfectly okay to look at the resources. I do it all the time. So now, what is this application? Well, this is a FLASK application that expects from the user a CSV file, which should have at least a column named address. For example, here is a CSV file. And you can see that we have an address column there, so the user should have a column called address, named address in there. Either with a lower or uppercase A, it doesn't matter. So you should build your application to recognize both address with a lowercase A and address with uppercase A. Now, the user can upload such file using the choose file button in here. And you can see that supermarkets was uploaded in there. And once the user uploads that file, they'll press submit. And this table shows up. So once the user uploads such a file, the backend of your application, so Python script will read that file, and it will add a latitude and longitude column, which are calculated out of the address column. So we're talking about geocoding and you know how to do geocoding. You learn that in the course in the Pandas section. And as you see, the result table is displayed on the web page once the user presses the submit button, and you can see the two columns in there. And lastly, you also want to allow the user to download the CSV version. So a file that contain this data. And therefore, you need to display a download button here as I did. So once the user presses download, a file is downloaded. This is a file. We also have some empty cells in there because Python was not able, so the geocoding service was not able to geocode this address to latitude and longitude. So yeah, you need to count for that and just pass some non values to those cells. Now, soon you may run into problems such as, you know, if the user uploads some other files, so let's change this to add instead of address, and I'll save this. So I don't have an address column in that file anymore, let me upload it again. Like that. Submit. And in this case, you want to show a message there saying that please make sure you have an address column in your CSV fall or something like that. So you don't want the program to crash to show flask error in there. So yeah, you need to try and accept some errors in there. And, that's it. At that point, you have built a geocoding service. I hope I was clear with explanations. But if you have questions, please ask them. I wish you good luck with this project. It will be tough but fun, and it's all about persistence. So if you commit to doing it, you'll do it. The next video is dangerous because I'll show you the solution in there. So please watch it as a last resort or watch it to compare your finished application with mine. And also, when you compare your solution with my solution, don't expect them to be the same. They will never be. I mean, there are different ways to make an application, and mine can be better than yours or the other way around. So please keep that in mind. And yeah, that's what I wanted to say. I hope you enjoyed my course. I also appreciate it if you left the review. I do look at all the reviews, and I appreciate them a lot. So yeah, thanks a lot, and I'll talk to you later. 226. Part 1 of Building the Geocoder Web App: Hey, welcome to this new lecture, and I hope you had an easy time trying to build the geocoding app. I know that should have been tough, but if you have gone through a certain point, that's great, too. In this lecture now, you get two things. The first thing is you'll find the attachment in the resources of this lecture. There you'll find all the files that contain the code for this web app. Specifically, you'll find four directories, so static templates, uploads, and visual, and also an app dot py file. Now here I happen to have four app files. But basically, the last one is the final version. So this is very basic the version one, where I just add a couple of functions in Python script, and then I added some more to these functions and then some more, and then I added. And then I eventually added some more code that completed the application. So this is what you get. And you'll find this in a zip file. So please download that. Yeah, that's the first thing you'll get in this lecture, the zip file of the solution code. And the second thing is, I'll go ahead now and explain how I approach this problem, and I'll show you the code and what I build first and second third and so on. So these are the four versions. I have version one, when I added some code, two, three, and four. So let's ignore this for a moment because the first thing I want to explain is the user interface. So we'll start from the front end first. Now, the first thing I did, though, was creating a directory structure. So I created an empty static folder, templates and uploads and virtual. So static and templates are standard for FLASK application. And the uploads folder will be just folder where I generate these intermediate files that the application makes available for download for users. You'll see that in just a bit. I also created this virtual folder lab, which is actually the directory of visual environment. So I made that with Python with the N flag Virtual Virtual for the name of the directory. So if you execute that, you'll get this directory with fresh installation of Python and PIP and other built in libraries. And then I went ahead and installed Flask and I installed Pandas because you will need pandas to read the data that the user is submitting and you want to calculate some columns there, and you also need Geopy to geocode those values from the pandas data frame. And those are the three third party libraries that you need to install. Once I created these empty directories, then the second step was to create the user interface. So what I did was I created an index dot HEML template in the templates folder. So at first, that was quite simple. So it didn't contain this much good. That simply contained, like, a ttle and some headings there and also a basic form. And initially, I didn't put anything in the action. So when the user submits, I had this submit button, and I also had this file type of input in there. So if you can remember it file, this is a form. We have this file input and the submit button. So these two and also restricted file submission to CSV only. And that's a form. I didn't have this in the beginning, so I won't go and explain this for now. I'll go through this later. Yeah, that was interface. Later, I went and created this main CSS file. So here you find the CSS styling for the webpage. I won't go into this now. This is quite self explanatory. So we have done CSS earlier in the course. And this file is also included in the resources among the other files, but I never expect that you have the same styling. So you may have some different things, some colors or sizings and so on. And then you go ahead and reference the CSS fall to the head tags. Yeah, basically, that's what I did in that second step. So first step creating a directory, and second step creating the basic interface and adding the CSS tolling to that. If you simply created the HTML code, and then later when you finish your application, you created a CSS file. That's perfectly okay too. Or even if you started with the Python file directly, that's also fine. Some developers start from the front end and some start from the back end. That's perfectly okay. So, once I had the interface, then I went ahead and created an app file. So an app dot py fol these four versions are just for demonstration for this video. So I made it for different files to show you the stages that I went through to build my final code. So Version one, this is what I did basically. I imported these libraries. So from FAS, I imported the usual FLASK class and normally render template method to return HML templates. And I knew that my application involved some user submission, so some post request. Therefore, I included the request method there as well, and then the sent file method, which is used to send a file to the browser for downloading. And yeah, that's about FAS, and then we want to geocode data, right? So I upload it from Geo Pi o coders, I input it nominating and also Pandas. Once I input it the dependencies, then I went ahead and created a FAS instance just here, and then three functions which for now, they don't do anything. So the first would be the homepage, as you here with this backslash. And I name that index, the function, and I simply return render template. And of course here goes index dot HML. So this will render the homepage, which is index dot HML. Then the next thing that you might expect is, you know, the user is in your web page. And once the user presses the choose fall button, and they select a file, and then they press submit. What you want to do when they press the submit button is you want now to load that file in Python, and you want to read that as a pandas data frame, and you want to calculate a coordinate column where you calculate the latitude and longitude from the address column using geo Pi. Then out of coordinates column, you want to calculate latitude and longitude. So we have done this previously in the course in the panel section, and then eventually, you want to return a data frame and you want to send that data frame via a render template method. You want to send that data frame here down here. So what we're talking here is we're talking about creating a function that does all this. So it reads the CZ fall and processes with panels, and then it displays the table. The data frame ASO table. And I created Sutter function and called the success table. If you remember, that has to have the methods parameter equal to post because we are expecting a post request. And then we have yet another function. I call this download fall. So that's the URL, success dash table, and this is a function name. That we have yet another URL and another function attached to that URL. So I call this download. As I said, every time the user does something, you want to create a decorator and a function attached to that. So first, the user will do a submission, and you want to capture that in this function. Success table, and then the next thing that the user will do is it will press the download button that will be displayed down here. And that has to trigger another function in Python, and that has to trigger the send file method in Python, so that we send the file to the user. That means we need another function here called download. At least that's how I named it. Anyhow, let's go to version two null. So see the difference here and here. The index function remains the same. So that's all we do for index. It's quite simple. We simply return the initial index that is ML template. And then here I've added quite a load of code. And basically, what we have is we check for the request. If we got a post request, then I get the file using request dot falls, and file here is the name. All the input in here. So yeah, what happens is that when the user presses the submit button that's on here, a URL is triggered, and then that URL is URL for the success underscore table function. So this function here. That means this function will be executed, and then we create a data frame there, which will read the fall this fall that we're getting from the user, from the user form. And then we do this nominating and we create a dataframe column there. You know this from the pandas section with apply method and then apply the geocode to the address column. And then out of the coordinates column, I get a latitude column, and I use a Lambda function to extract the latitude from each of the coordinates rows, and also count for n values there. And then I don't need this coordinates column. So I just drop that using the drop method, and then I convert this to a CSV. Here I'm generating a CSV file. This is the output that we want to give to the user. And I'm sorting this in the uploads folder. So you just need to pass the path there, the relative path uploads Geocode. That's how I'm naming this. At the moment later I'll do something more advanced. So let's name it geocoded for now, that CSV. And then what this will do, it will return a template, so it will return the index that template. But then if you look here, let me open this to another view. Yeah, here we have a division. Node the ginger to syntax that I'm using there. So I'm including the BTN variable, and I'm ignoring when that is missing. Now, this is different from here up here. Here, I'm returning HML as a string. And here I'm returning an HML template. So the syntax is different. And this is also different from when we use extend. So when we extend a layout, you extend a layout when you want that as soon as the user visits, let's say the index that HD Melt template, the index that HM Meltem plate will display other HML templates. So it will extend as soon as the user visits that index not HML pages the homepage. This is different because we don't want this to be displayed right away. That's why you're saying ignore missing, so ignore that when it's missing. And include it only when the user is visiting this success dash table URL. And when the user visit that, so when the user presses submit, after having submitted a file, then you want to render this download HTML template. So what this contains is a button here. You want to generate a button there, which should be, you know, rue fall, submit. So yeah, you get this download file in there and you also get the HML table. So the data frame has an HML table. So the first row, the second row, the first row, the second row. Anyhow, that bottom now is attached to a reference, which suggests that when the user presses download, the URL for the Python download function will be visited. So we go here, and this URL of the download function will be visited I know what we want to do when the user visits this URL is we want to return Send file method. Actually, this should be uploads geocoded dot CSV. So we want to send to the user the file that we generated up here earlier in this function. We want to send that to the user under the name youfle dot CSV. And also as attachment to, you know this code from the previous lectures. And, that's about the download that SML template. And, we're basically done. I mean, you can get away with this version of the program, and it'd be almost excellent if you went this far. However, we may have some small problems with this. The problem would be if you choose a file, a CZ file that doesn't have an address column inside, so a column named address, then what would happen is you'd be able to load that file as a dataframe, and then when you try to create a new column in the dataframe called coordinates, and then you try to access an existing column named address in the data frame, a Python will throw an arrow and it will stop the application. That means when the user visits the success table URL, they will be shown an error page. And that is not very user friendly to. What you might want to do instead is you may add some functionality here that checks if the data frame, if the is a file entered by the user, so you want to read the file as a data frame. And then in the data frame, check if you have an address column. If you have one, then you go ahead and do the calculations. But if you don't, then you return something to the user. So instead of returning DF to HTML, you return a message saying that sorry, you don't have such a column or so default. So yeah, I'll show you the code for that in the next lecture. So see 227. Part 2 of Building the Geocoder Web App +: Great. We are in version two, and I'll try to be quick now and show you version three. This is version three. The way I implemented this functionality where I want to check if there is an address column in the data frame is by adding a try and expect statement. So basically, if you can see the difference is I get the file, and then I try to read that file. Or this could also be outside of a try keyword. That wouldn't be a problem and C outside of a try keyword as well. However, this is still better because you may also want to check for users sending files that are not CSV. So here we're checking, actually, that the user is submitting a CSV file. However, that only means that the file has a dot CSV extension in the file lane. However, that doesn't mean that the file is actually CSV. So you may have, let's say, an MP four file and you have changed the extension to CSV, but that's still an MP four file. So what you want to do is, um you want to include DF inside the try and expect block. If Python is not being able to create a data frame out of an Epi file, then it will throw an error. So that's what actually happens if you pass EPiourFle, you wouldn't be able to read it as a dataframe. So yeah, you want to include that in here, then you return the same, so I haven't changed anything here. You return the same template index at HML, and you send the HML there and the button. Except if there is an error, what you do is you return the index not HML, but then instead of the HML table, you want to return this message. And of course, you don't want to return any download button in there. A, that should do it. And that's about version three. So those were the differences. Now, Version four, what I have there. Well, if you see here, we got this geocoded CSV fall. Now, that's a string. That means that a geocode CZ file will be created for all the users that will be submitting data. Now, that may cause some problems because if two users are submitting data at the same time, you may have some name clashes there. So what you could do here is you could use a datat module to generate unique names for every generated file. And that's what I did. So here is version four. I put it the days time module in here, and then I'm generating the geocoded CSV file in here, so DF to CSV file name. And I made this file name global in here because I also want to access it from the download function in here. So again, I want to generate that in here, I'm generating a file name. Then in the file name, we have the upload string, which will point to the directory where this file will be. And then we have the slash. And actually, this plus shouldn't be there. So just after the slash, we have the file name. And that would be, you know, we have year, and then we have the month and then the day and then the hour and the minutes and seconds and milliseconds. And then the dot CSV extension in the file name. So yeah, this is quite unique for every user because we have milliseconds in there. But let me show you how this looks like, actually. So again, the user chooses a file, submit, and when they press submit, a Python will generate the data frame and it will also generate the CC file. So in this line here. And you can now find that CC file in the uploads folder. So this was generated earlier, and this is the file. That's the file that we just generated. Then when the user presses download, that file will be downloaded, but with your file name, which is this one here. Anyhow, what happens is that the function will get the path of the file that it has to download in the browser will get the fall name from this global variable. That's why I'm passing this as a global variable so that I can access the value of it, which is generated in here, I can access this value from another function. And yeah, that's my version of the application. I know this is not like your version. I hope you were close as much as possible, and it would be great if you did it better than me. In either case, I'm sure that trying to solve this application should have improved your problem solving skills in Python because that at least will position you, so we'll define your level, your Python level so that you can fill the gaps that you really think are not your strongest points. That was about this lecture, and I'll see you.