Full width home advertisement

Post Page Advertisement [Top]

Python | CS50W | CS50's Web Programming with Python and JavaScript | edX

Lecture 2 - CS50's Web Programming with Python and JavaScript

Python

Python

Python is a very powerful and widely-used language that will allow us to quickly build fairly complicated web applications. 

>> print("Hello, world!")

- There is a 'print' function built in to the python language, that takes an argument in parentheses, and displays that argument on the command line. 
- Type this line into your text editor of choice, and then save the file as 'something.py'. Next, head over to your terminal, navigate to the directory containing your file, and type 'python something.py'. 
- Depending on how your computer is set up, you may have to type 'python3' instead of 'python' before the file name.
- Python is an interpreted language: When you type 'python file.py in your terminal, a program called an interpreter, which you downloaded together with Python, reads through your file line by line, and executes each line of the code. This is different than languages like C or Java, which need to be compiled into machine code before they can be run. 

Variables

>> a=28, b=1.5, c="Hello", d=True, e=None 
(int, float, str, bool, NoneType)

- Each of these lines is taking the value to the right of the '=', and storing it in the variable name to the left. 
- NoneType, which only has one possible value, this capital N, none. None as a value we'll use whenever we want to represent the lack of a value somewhere. So if we have a function that is not returning anything. None can be useful if ever you want a variable to represent the absence of something, for example. 

> A program that can take input from the user and say hello to that user. 
>> name = input("Name: ")
>> print("Hello, " +name)

- Use built in function called 'input' which displays a prompt to the user, and returns whatever the user provides as input. 
- In the first line, instead of assigning the variable name to an explicit value, we're assigning it to whatever the 'input' function returns. 
- In the second line, we're using the '+' operator to combine, or concatenate, two strings. In python, the '+' operator can be used to add numbers or concatenate strings and lists. 

Formatting Strings

- There are even easier ways to work with strings, known as formatted strings, or f-strings for short. 
- To indicate that we're using formatted strings, we simply add an 'f' before the quotation marks. 
>> print(f"Hello, {input("Name: ")}")

Conditions

We can run different segments of code based on different conditions. 

- Change the output depending on the number a user types in.
>> num = input("Number: ") #num = int(input("Number: "))
>> if num>0:
>>    print("Number is positive")
>> elif num<0:
>>    print("Number is negative")
>> else: 
>>    print("Number is 0")

- Conditionals contain a keyword 'if', 'elif', 'else' and then a boolean expression, or an expression that evaluates to either 'True' or 'False'. 
- All of the code we want to run if a certain expression is true is indented directly below the statement. Indentation is required as part of the Python syntax. Because Indentation is how the program knows what code is inside of the if statement and what is outside. 
- In some languages, like C or HTML, the indentation isn't strictly required by the computer to be able to parse and understand what's inside the program. 

- If we run the above program, a TypeError:'>' not supported between instances of 'str' and 'int' will occur.
- TypeError means there's some mismatch of types, that Python expected something to be of one type but it turned out to be a different type. 
- In this case, 0 is an enteger, so it must be the case that 'num' variable is a string. This is happening because it turns out that the 'input' function always returns a string, and we have to specify that it should be turned into an integer using the 'int' function. 
So modify the first line like this: num = int(input("Number: "))

Sequences

- Mutable(<->Immutable): Once a sequence has been defined, we can change individual elements of that sequence. 
- Ordered(<->Unordered)

Data Structures

list: Sequence of mutable values
tuple: sequence of immutable values
set: collection of unique values
dict: collection of key-value pairs

Strings

Ordered / Immutable
- We can access individual elements within the string. 

>> name="Harry"
>> print(name[0])

- Prints out the first(index 0) character in the string => 'H'
- The square bracket notation takes a sequence, some ordered sequence of elements, and gets me access to one particular element inside of that sequence. 

Lists

Ordered / Mutable
- A Python list allows you to store any variable types. We can print an entire list, or some individual elements. 
- Append: Add elements to a list
- Sort: Sort a list in alphabetical order. 

>> name = ["Harry", "Ron", "Hermione"]
>> print(names)  #['Harry', 'Ron', 'Hermione']
>> print(names[1])  #Ron
>> names.append("Draco")
>> names.sort() 
>> print(names)  #['Draco', 'Harry', 'Ron', 'Hermione']

Tuples

Ordered / Immutable
- Tuples are generally used when you need to store just two or three values together, such as the x and y values for a point. In Python, use parentheses. 

>> point = (12.3, 14.5)

Sets

Unordered / Mutable(N/A)
- If you don't care about the order of the elements and you know that all the elements are going to be unique, use sets. 
- Sets are different from lists and tuples in that they are unordered.
- They are also different because while you can have two or more of the same elements within a list/tuple, a set will only store each value once. 
- 'set': Define an empty set
- 'add': Add elements from the set
- 'remove': Remove elements from the set
- 'len': Find the set's size. Works on all sequences in Python.
- Despite adding '4' and '3' to the set twice, each item can only appear once in a set. 

>> s=set() #Create an empty set
>> s.add(1) #Add some elements
>> s.add(2)
>> s.add(3)                                                                                             
>> s.add(4)
>> s.add(3)
>> s.add(1)
>> s.remove(2) #Remove 2 from the set
>> print(s) #{1, 3, 4}
>> print(f"The set has {len(s)} elements.")

Dictionaries

Unordered / Mutable
- A dictionary is a set of key-value pairs, where each key has a corresponding value. 
- In Python, use curly brackets to contain a dictionary, and colons to indicate keys and values. 

houses = {"Harry": "Gryffindor", "Draco": "Slytherin"} #define a dict={"key":"value"}
print(houses["Draco"]) #Slytherin
houses["Luna"] = "Ravenclaw" #Adding values to a dict dict["key"]="value"
print(houses["Luna"]) #Ravenclaw

Loops

> for loops
- To iterate over a sequence of elements, performing some block of code for each element in a sequence. 
>> for i in [0, 1, 2, 3, 4, 5]:
        print(i) 

- We can condense this code using the python 'range' function, which allows us to easily get a sequence of numbers. 
>> for i in range(6):
        print(i)

>> names = ["Harry", "Ron", "Hermione"]
>> for name in names:
        print(name)

- We can get more specific, and loop through each character in a single name.
>> name="Harry"
>> for char in name: 
        print(char)

Functions

#functions.py
>> def square(x):
        return x*x

- 'def': Define a function                                                                             
- 'return': What the function's output should be
- We can call this function just we've called other ones: using parentheses

#square.py
>> for i in range(10):
        print(f"The square of {i} is {square(i)}") #~The square of 9 is 81


Modules

- It will become useful to be able to write functions in one file and run them in another. 
- When we try to run 'square.py', we run into the following error: NameError: name 'square' is not defined
- We have to explicitly 'import' the square function from the 'functions' module we just wrote. 

#square.py
>> from functions import square  #just import the name square into this file entirely. 
>> for i in range(10):
        print(f"The square of {i} is {square(i)}")

- Alternatively, we can choose to import the entire 'functions' module and then use dot notation to access the 'square' function:
>> import functions  #import the entire module 
>> for i in range(10):
        print(f"The square of {i} is {functions.square(i)}") 
#Go inside the functions module, get the square function and run that function. 

- There are many built-in Python modules such as 'math' or 'csv'. 

Objected-Oriented Programming 

- Objected Oriented Programming is a programming paradigm, or a way of thinking about programming, that is centered around objects that can store information and perform actions. 

- Classes: A Python Class is essentially a template for a new type of object that can store information and perform actions. 

class Point():
    def __init__(self, x, y): #A method defining how to create a point
        self.x = x
        self.y = y

p = Point(2,8)
print(p.x) #2
print(p.y) #8

- __init__: A method or function that is going to automatically be called every time that I try to create a new point.  
- 'self': To represent the object we are currently working with. Self should be the first argument for any method within a Python class. 
- All functions that operate on objects themselves
- Use dot notation to say, go into the point and access data that is stored inside of that point. 

class Flight():
    def __init__(self, capacity): #Method to create new flight with given capacity
        self.capacity = capacity
        self.passengers = []  #Create a empty list
    def add_passenger(self, name): #Method to add a passenger to the flight
        self.passengers.append(name)

- def add_passenger(self, name): This is a method that's going to work on an individual object, we need some way of referencing that object itself. => use 'self'
-> This class is flawed because while we set a capacity, we could still add to many passengers. Let's augment it so that before adding a passenger, we check to see if there is room on the flight. 

<Code>
class Flight():
    def __init__(self, capacity): #Method to create new flight with given capacity
        self.capacity = capacity
        self.passengers = []
    def add_passenger(self, name): #Method to add a passenger to the flight
        if not self.open_seats():
            return False
        self.passengers.append(name)
        return True
    def open_seats(self): #Method to return number of open seats
        return self.capacity - len(self.passengers)

- if not self.open_seats(): To determine whether or not there are open seats. 
- In Python, the number 0 can be interpretted as meaning 'False', and we can also use the keyword 'not' to signify the opposite of the following statement. So 'not True' is 'False', and 'not False' is 'True'. 
- If 'open_seats' returns 0, the entire expression will evaluate to True. 

<Code>
flight = Flight(3) #Create a new flight with up to 3 passengers
people = ["Harry", "Ron", "Hermione", "Draco"] #Create a list of people
for person in people: 
    if flight.add_passenger(person):
        print(f"Added {person} to flight successfully")
    else:
        print(f"No available seats for {person}")

Functional Programming

Python supports the Functional Programming Paradigm, in which functions are treated as values just like any other variable. 

Decorators

One thing made possible by functional programming is the idea of a decorator, which is a higher-order function that can modify another function. 
- A decorator is going to be a function that takes a function as input and returns a modified version of that function as output. 
- Functions are themselves values. 
- We can apply this decorator using an @(at) symbol. 

<Code>
def announce(f): 
    def wrapper():
        print("About to run the function")
        f()  #Run the function f
        print("Done with the function")
    return wrapper #Return a new function

@announce #Add the Announce decorator to this function 
def hello():
    print("Hello, world") 

hello() 

- Taking the function f, and creating a new function that just announces, via a print statement, before and after the function is done running. 
Wraps up the function f with some additional behaviour, so this is called a wrapper function. 
- Hello function that just printed "Hello, world" is wrapped inside of the Announce decorator, where what the Announce decorator does, is it takes our Hello function of input and gets us a new function that first prints an alert warning that we're about to run the function, actually runs the function, and then prints another message. 

Lambda Functions

Lambda functions provide another way to create functions in Python. 

#Square.py
square = lambda x: x * x

- Where the input is to the left of the ':' and the output is on the right. 
- This can be useful when we don't want to write a whole separate function for a single. 
- For example, if we want to sort some objects where it's not clear at first how to sort them. 
- Ex) We have a list of people, but with names and houses instead of just names that we wish to sort.

people = [
    {"name": "Harry", "house": "Gryffindor"},
    {"name": "Cho", "house": "Ravenclaw"},
    {"name": "Draco", "house": "Slytherin"},
]
people.sort()
print(people)

-> TypeError: '<' not supported between instances of 'dict' and 'dict'
- 'people.sort()' is causing a type error because it's trying to use less than to compare two dictionaries. 
- Python doesn't know how to sort these dictionaries. 
- I need to tell the sort function how to sort these people. 
- Define a function that tells the sort function how to do the sorting. 

people = [
    {"name": "Harry", "house": "Gryffindor"},
    {"name": "Cho", "house": "Ravenclaw"},
    {"name": "Draco", "house": "Slytherin"},
]

def f(person):
    return person["name"]

people.sort(key=f) #We get the names in alphabetical order. 
print(people)

#Use a lambda function
people = [
    {"name": "Harry", "house": "Gryffindor"},
    {"name": "Cho", "house": "Ravenclaw"},
    {"name": "Draco", "house": "Slytherin"},
]
people.sort(key=lambda person: person["name"]) #Input: Output
#A Lambda which is a function that takes a person and returns the person's name. 
print(people)

Exceptions

#Code
x = int(input("x: "))
y = int(input("y: "))
result = x/y
print(f"{x}/{y}={result}")

- In many cases, this program works well. But when we attempt to divide by 0, we'll run into problems: ZeroDivisionError: division by zero

#Code: Using Exception Handling
import sys

x = int(input("x: "))
y = int(input("y: "))

try:
    result = x/y
except ZeroDivisionError:
    print("Error: Cannot divide by 0.")
    sys.exit(1)
print(f"{x}/{y}={result}")

try to divide the two numbers, except when we get a ZeroDivisionError
- sys.exit(1): Exit the program with a status code of 1, where a status code of 1 means something went wrong in this program. 
- try-except expression: Try to do this except if this exception happens, rather than have 
the program crash, just print out this error message, and then exit the program. 
- We still run into an error when the user enters non-numbers for x and y: ValueError: invalid literal for int() with base 10: 'hello'
- 'hello' cannot be converted into a base 10 integer. You can't take text that is not a number and turn it into an integer. 

import sys

try: 
    x = int(input("x: "))
    y = int(input("y: "))
except ValueError:
    print("Error: Invalid input")
    sys.exit(1)

try:
    result = x/y
except ZeroDivisionError:
    print("Error: Cannot divide by 0.")
    sys.exit(1)

print(f"{x}/{y}={result}")

- Just try to get the input except if a value error happens. 

댓글 없음:

댓글 쓰기

Bottom Ad [Post Page]