From 444c5b1483b065b00ca538daa7889699c3597e02 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 13 Sep 2023 12:16:34 -0400 Subject: [PATCH 001/101] examples covering the basics of using functions --- function_basics.py | 147 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 function_basics.py diff --git a/function_basics.py b/function_basics.py new file mode 100644 index 0000000..4a4f20e --- /dev/null +++ b/function_basics.py @@ -0,0 +1,147 @@ +################################################################################ +# +# Program: Function Basics Examples +# +# Description: Examples covering the basics of using functions in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Qx_Gu-9lTqc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The function returns the feeling input by the user after greeting them. +# +# The variable person_name is called a parameter, it will be st to the argument +# that is supplied when the function is called. If a person_name argument is +# not supplied the default value for the person_name parameter will be "John". +# The indented block of code is the "function body". The block of code will +# run whenever we call the function. The return statement at the end of the +# function is what returns the feeling value to where the function is called. +def greetings(person_name = "John"): + print("Hi", person_name) + print("How are you feeling?") + feeling = input("Feeling: ") + return feeling + +# We call the function with the argument "Ron", we say that we pass the argument +# to the function. We store the returned string into the variable ron_feeling, +# and we can then use that returned value in the rest of our program. +ron_feeling = greetings("Ron") +print("Ron is feeling", ron_feeling) + +# We can call a function multiple times in our code. This allows us to repeat +# the execution of a block of code without repeating the actual block of code +# itself in our code, which makes our code shorter, and less repetitive! +# +# harry_feeling = greetings("Harry") + +# If we call greetings() without an argument, the default value for person_name +# will be used. +# +# john_feeling = greetings() + + +# The operations function returns the addition, difference and product of +# two numbers. +# +# Functions can accept more than one argument and return more than one value, +# here we have multiple parameters (x and y) and we separate them by commas. +# We separate our return values by commas as well to return multiple values. +def operations(x, y): + return x + y, x - y, x * y + +# Here was pass the values 10 and 5 to the operations function when we call it, +# note that by passing the variable 'a' to the function what is really being +# passed is the value 10. We store the 3 values returned by the function +# into the variables sum, diff and prod. +# +# Technically what's happening here is a little more involved than what is +# described above in a beginner-friendly way. :-) Technically the function +# returns a tuple and we "unpack" the tuple, see this video for more +# details: https://www.youtube.com/watch?v=Q2PJ-LNS3FI +# +a = 10 +sum, diff, prod = operations(a, 5) + +# Output the returned values. +print("Sum:", sum) +print("Diff:", diff) +print("Prod:", prod) + + +# A function that outputs the parameter x3 value +def output(x1,x2,x3): + print("x3:", x3) + +# We can pass function arguments out of order by using keyword arguments, i.e. +# by giving the parameter name = the value we wish to pass as an argument. Here +# the x3 parameter will be set to "yes" and the others set to "no". +output(x3 = "yes", x1 = "no", x2 = "no") + + +# Function adds one to a value and outputs the new value. +# +# Note that the x parameter is a different variable than the x variable below +# even though they have the same name. The x parameter variable is 'local to +# the function', which means it has the scope of the function, i.e. it exists +# only in the function. +# +# In Python variables reference objects in memory. When we pass a variable to +# a function, what gets passed is a reference to an object, not a "copy" of +# the value/object. So below, when x is passed to modify, the parameter x +# is going to reference the same Integer 10 object in memory as the variable +# x that was passed to the function! +# +# Now Integers in Python are immutable, this means in the modify function +# when we add 1 to x, the Integer object is not modified. Instead a new +# Integer 11 object is created, and the x parameter now references this new +# object. When we output x inside the function, we'll get '11' as output. +# +# Notably though, the x variable outside the function is still referencing +# the same Integer 10 object, and when we output this variable after the +# function call, we'll get '10' as output. +# +# This is the type of behavior we can expect when we pass immutable +# objects to a function. +# +def modify(x): + x = x + 1 + print("x:", x) + +x = 10 +modify(x) +print("x:", x) + + +# The function appends the value 4 to the list it is passed. +# +# Lists in Python are mutable objects. This means we can actually +# modify the object. +# +# When we pass an mutable object to a function, again what's being +# passed is a reference to the object. So when we pass the list 'l' +# to the function, what is passed is a reference to the list, and then +# the parameter variable 'l' will reference the SAME list. +# +# So in the function when we append '4' to the list, it doesn't create +# a new list. Instead, '4' is added to the existing list. This is +# because lists in Python are mutable. +# +# So then when we output the list 'l' after calling the function, we'll +# get [1,2,3,4], because the variable 'l' outside of the function is +# referencing that same list that we modified IN the function. +# +# Again we need to be aware of how mutable objects will be behave +# when we pass them to a function. +# +def modify_list(l): + l.append(4) + +l = [1,2,3] +modify_list(l) +print("l:", l) + + + + From 71fc982e359aae27fe5021d24d0abdda5a209074 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 18 Sep 2023 22:15:37 -0400 Subject: [PATCH 002/101] functions with arbitrary argument examples --- functions_arbitrary_arguments.py | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 functions_arbitrary_arguments.py diff --git a/functions_arbitrary_arguments.py b/functions_arbitrary_arguments.py new file mode 100644 index 0000000..d1ea619 --- /dev/null +++ b/functions_arbitrary_arguments.py @@ -0,0 +1,60 @@ +################################################################################ +# +# Program: Functions with Arbitrary Arguments +# +# Description: Examples of creating functions with an arbitrary number of +# arguments and an arbitrary number of keywords arguments in Python. Functions +# like these are also know as variadic functions. +# +# YouTube Lesson: https://www.youtube.com/watch?v=nb6UpZRltKU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# - We can use *parameter_name to have a function accept an arbitrary number +# of non keyword arguments. +# +# - The convention is to use args for the parameter name. +# +# - The parameter will be set to a tuple containing the arbitrary number of +# arguments provided. +# +# - We can access and output these items with args[0], args[1], etc. +# +# - We can have parameters like x before *args. Notice how below the +# argument 1 is assigned to x, and then 2 and 3 are assigned to the tuple +# args. +# +# - We can even have parameters like y after *args, but we need to then supply +# the arguments as keyword arguments like y=4. +# +def arbitrary1(x, *args, y): + print(type(args)) + print("x:", x) + print("args[0]:", args[0]) + print("args[1]:", args[1]) + print("y:", y) + +arbitrary1(1,2,3,y=4) + +# - We can use **parameter_name to have a function accept an arbitrary number +# of keyword arguments. This must be the last parameter in the list. +# +# - The convention is to use kwargs for the parameter name. +# +# - The parameter will be set to a Python dictionary with the keys/values of the +# dictionary set to the keys/values of the keyword arguments. +# +# - We can have parameters like x before **kwargs and even an arbitrary number +# of non keyword arguments with *args before **kwargs. +# +def arbitrary2(x, *args, **kwargs): + print(type(kwargs)) + print("x:", x) + print("args[0]:", args[0]) + print("args[1]:", args[1]) + print("First Name:", kwargs["fname"]) + print("Age:", kwargs["age"]) + +arbitrary2(100, 10, 20, fname = "Joe", age = 23) \ No newline at end of file From 4980470b2f565ed90537fad9130aa797f1966405 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 19 Sep 2023 20:55:16 -0400 Subject: [PATCH 003/101] lambda function examples --- lambda_functions.py | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lambda_functions.py diff --git a/lambda_functions.py b/lambda_functions.py new file mode 100644 index 0000000..4251a5e --- /dev/null +++ b/lambda_functions.py @@ -0,0 +1,76 @@ +################################################################################ +# +# Program: Lambda Functions +# +# Description: Examples of lambda functions in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=N4aphT88u78 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Lambda functions are a special type of small anonymous function in Python. +# +# We define a lambda function using: +# +# lambda [parameters] : expression +# +# Where [parameters] could be empty, or it could be a single parameter like +# "x" or multiple parameters like "x,y,z". The return value of the function +# is the result of the expression. Lambda functions cannot contain statements +# like if-statements, or be used with annotations. +# +# The below defines a lambda function that adds one to the parameter x. We +# assign the lambda function to the variable add_one so we can use add_one +# as a name for the function. +# +add_one = lambda x : x + 1 + +# This function is equivalent to this function below... +# +# def add_one(x): +# return x + 1 + +# Call add_one and pass it 5 as an argument, we'll get 6 back as a result, which +# we output using print. +print(add_one(5)) + +# We could have a lambda function with NO parameters like this that simply +# returns 10... +# +# add_one = lambda : 10 + +# Lambda functions don't have a name, that's why we call them anonymous +# functions. Below we define a lambda function with two parameters x,y which +# we separate using commas, and the lambda function returns the product of x and +# y. We then *call* this function we've defined by surrounding it with brackets +# ( ... ) and passing the arguments 10 and 5 and with (10,5). +# +print( (lambda x,y : x * y)(10, 5) ) + +# Define a list of numbers +numbers = [1,2,3,4] + +# Define a function that double's the number its passed +def double(x): + return x * 2 + +# We could double the numbers in the numbers list by passing the double +# function to map along with numbers. The map function will call the double +# function for each number in the numbers list, with each number being passed to +# the function one after the other, and map() will return a map object +# containing the returned values. +# +# doubled = map(double, numbers) + +# One use case for lambda functions is to avoid having to create a function with +# a name for simple cases like this where we need a simple function that we will +# use only one place in our code. We could just define and pass a lambda +# function to map "inline" like this, saving space and making our code +# potentially easier to read as all the information is on one line. +# +doubled = map(lambda x : x * 2, numbers) + +# Convert the doubled map to a list and output the doubled numbers +print(list(doubled)) \ No newline at end of file From 1445cf4aacf76d7e77056e1439b9fa3e6964deaa Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 4 Oct 2023 20:13:37 -0400 Subject: [PATCH 004/101] inner function example --- inner_functions.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 inner_functions.py diff --git a/inner_functions.py b/inner_functions.py new file mode 100644 index 0000000..1828ace --- /dev/null +++ b/inner_functions.py @@ -0,0 +1,81 @@ +################################################################################ +# +# Program: Inner Function +# +# Description: Example of using an inner function in Python, also known as a +# nested function. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ZH8IlWHONcE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We can define an "inner function" also known as a "nested function" inside +# another function, was the inner() function here is defined inside the +# outer() function. + +def outer(x): + + # creates a local variable y of the outer() function + y = 5 + + # inner functions can have their own parameters, like z + def inner(z): + + # We can use z as we would a parameter of any function, e.g. to output the + # value here... + print("z:", z) + + # Variables like x that are in the local scope of the function + # outer() are what are in the "enclosing scope" of the inner() + # function. We can access the values of these variables like this... + print("x:", x) + + # If we want to modify a variable in the enclosing scope, like y which is + # a local variable of the function outer() but in the enclosing scope + # of inner(), then we need to use "nonlocal" as we do below. This will + # give inner() the ability to actually modify y. If we did not use + # "nonlocal y", then "y = 50" would actually create a NEW local variable + # of the inner() function called y. + nonlocal y + y = 50 + print("y:", y) + + # We can access any variable in the enclosing scope that is created before + # the inner function is called... here we access "a" which was created + # just before calling the inner function. + print("a:", a) + + # We cannot access "b" because it is created AFTER the inner function is + # called... + # + # print("b:", b) + + # We can create local variables of the function inner(), but they will not + # be accessible in the outer function. + c = 50 + + + # creates a local variable a of the outer() function + a = 1 + + # call the inner() function and pass it the value 2 as an argument + inner(2) + + # Notice how the variable y of the outer() function has been modified and set + # to 50 by the inner function... + print("y:", y) + + # The inner() function cannot access this variable "b" because it is created + # AFTER the inner() function is called. + b = 2 + + # The outer() function cannot access a local variable of the inner() + # function "c", the below would cause an error... + # + # print("c:", c) + + +# Call the outer() function +outer(10) \ No newline at end of file From e0d24755a1e6042fac00d50dfc4362faba4a0cc3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:05:25 -0400 Subject: [PATCH 005/101] nonlocal keyword examples --- nonlocal_keyword.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 nonlocal_keyword.py diff --git a/nonlocal_keyword.py b/nonlocal_keyword.py new file mode 100644 index 0000000..c67457f --- /dev/null +++ b/nonlocal_keyword.py @@ -0,0 +1,38 @@ +################################################################################ +# +# Program: nonlocal Keyword Example +# +# Description: Example of using the nonlocal keyword in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=27S2qRdH2rM +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +def outer(): + + # This variable is in the "enclosing scope" of the inner function below + enclosing_scope_variable = 10 + + def inner(): + + # In order to give the inner function access to the enclosing_scope_variable + # we must use nonlocal like this. Try commenting out the below line to see + # the difference. If we do not do this, instead a new variable local to + # the inner function called 'enclosing_scope_variable' will be created, + # and it will be different than the enclosing_scope_variable of the outer + # function. And so in that case assigning 20 to enclosing_scope_variable + # would not change THAT variable's value (the variable in the enclosing + # scope of inner, which is the local scope of outer). Instead because + # we use nonlocal, inner will be given the same enclosing_scope_variable + # as in the enclosing scope, and we DO change that variable's value! + # + nonlocal enclosing_scope_variable + enclosing_scope_variable = 20 + print("inner:", enclosing_scope_variable) + + inner() + print("outer:", enclosing_scope_variable) + +outer() \ No newline at end of file From a73e74c511132bf16a4573462b052c6b10d28eb3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:06:01 -0400 Subject: [PATCH 006/101] nonlocal keyword usage example --- nonlocal_keyword.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nonlocal_keyword.py b/nonlocal_keyword.py index c67457f..0fb7250 100644 --- a/nonlocal_keyword.py +++ b/nonlocal_keyword.py @@ -4,7 +4,7 @@ # # Description: Example of using the nonlocal keyword in Python. # -# YouTube Lesson: https://www.youtube.com/watch?v=27S2qRdH2rM +# YouTube Lesson: https://www.youtube.com/watch?v=27S2qRdH2rM # # Author: Kevin Browne @ https://portfoliocourses.com # @@ -35,4 +35,4 @@ def inner(): inner() print("outer:", enclosing_scope_variable) -outer() \ No newline at end of file +outer() From cf6ee711fa5a067e6aa3433e2679a82101321bbb Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:51:32 -0400 Subject: [PATCH 007/101] global keyword examples --- global_keyword.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 global_keyword.py diff --git a/global_keyword.py b/global_keyword.py new file mode 100644 index 0000000..f90177b --- /dev/null +++ b/global_keyword.py @@ -0,0 +1,62 @@ +################################################################################ +# +# Program: global Keyword Examples +# +# Description: Examples of using the global keyword in Python which allows us +# to create and assign to global variables inside of functions. +# +# YouTube Lesson: https://www.youtube.com/watch?v=-t52p5pMAGU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Using the keyword global outside a function has no effect, we can create a +# global variable x simply by assigning to it. +global x +x = 20 + +def function(): + + # This will allow the function to assign to the global variable x + global x + + # If we did not have the statement above, this statement would actually + # create a NEW variable x that is local to this function + x = 10 + + # Output the value of the variable x + print("x function:", x) + + # global can also be used to create global variables inside of a + # a function, here we create a new global variable called new_variable + global new_variable + new_variable = 200 + + # The global keyword can also be used to create and assign to global + # variables inside of inner() functions, uncomment the below code to + # see the effect. + # + # def inner(): + # global x + # x = 30 + # print("x inner:", x) + # + # inner() + + +# If we try to access new_variable before calling the function it won't yet +# exist because the function is what creates it! Uncomment the below +# statement to see... +# +# print("new_variable:", new_variable) + +# the function will modify the global variable x and set it equal to 10 +function() + +# We can output x to see it is now set to 10. Try to comment out the +# "global x" statement inside the function to see the difference. +print("x outside:", x) + +# The call to the function will create the global new_variable +print("new_variable:", new_variable) \ No newline at end of file From daf90ef1299b2a3e1fb6d74343564f42762380a5 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:57:41 -0400 Subject: [PATCH 008/101] IsItWater API example, checks if water/land coords --- isitwater_api.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 isitwater_api.py diff --git a/isitwater_api.py b/isitwater_api.py new file mode 100644 index 0000000..24a3eba --- /dev/null +++ b/isitwater_api.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Check If A Location Is On Land Or Water +# +# Description: Example of using the IsItWater API to check if a coordinate is +# on land or water with Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=H32xQz8r8yA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The api is used according to the documentation available here: +# https://isitwater.com/ + +# The requests module is used to make the http request to the API +import requests + +# An api key is required, this API key will be disabled so you must obtain +# your own by registering using the above URL. +api_key = "fb7a7088ccmsha0a1556ab1f0ac9p19678fjsn9151e331d519" + +# This is the api "endpoint" where the request must be made +url = "https://isitwater-com.p.rapidapi.com/" + +# We include the API key in the request query parameters, along with a +# latitude and longitude for a geographic coordinate +params = {"rapidapi-key" : api_key, + "latitude" : "19.241244", + "longitude" : "72.888650"} + +# Makes the get request with the endpoint and parameters and returns a response +# object. The response will be made up of JSON data. +response = requests.get(url, params) + +# We use the .json() method to obtain a Python dictionary of the response data. +data = response.json() + +# Output the response data. The key water will be set to True if the coordinate +# is on water, and false if the coordinate is on land. +print(data) \ No newline at end of file From 73fd995a57d0b5cc07f14c616e5c0d1a762d617f Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 13 Oct 2023 23:30:45 -0400 Subject: [PATCH 009/101] replace all occurrences of a string in a file --- replace_string_file_occurrences.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 replace_string_file_occurrences.py diff --git a/replace_string_file_occurrences.py b/replace_string_file_occurrences.py new file mode 100644 index 0000000..df4c64a --- /dev/null +++ b/replace_string_file_occurrences.py @@ -0,0 +1,29 @@ +################################################################################ +# +# Program: Replace All Occurrences Of A String In A File +# +# Description: Program to replace all occurrences of a string in a file with +# another string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=uoF4xBrrQMI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt user for filename, text to find, and replacement text +filename = input("Filename: ") +find = input("Find Text: ") +replace = input("New Text: ") + +# Open the file for reading, read all file text and store into the variable +# contents, and then create new contents string by replacing all text to find +# with the replacement text +with open(filename) as file: + contents = file.read() + contents = contents.replace(find,replace) + +# Open the file for writing and write the new contents string to the file as the +# file contents +with open(filename, "w") as file: + file.write(contents) \ No newline at end of file From 988bedf6c23c86760cbc6f8727b9d2b3a047bc62 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 14 Oct 2023 15:49:34 -0400 Subject: [PATCH 010/101] print list items on seperate lines --- print_list_items_separate_lines.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 print_list_items_separate_lines.py diff --git a/print_list_items_separate_lines.py b/print_list_items_separate_lines.py new file mode 100644 index 0000000..bfb30b5 --- /dev/null +++ b/print_list_items_separate_lines.py @@ -0,0 +1,26 @@ +################################################################################ +# +# Program: Print List Items On Separate Lines +# +# Description: Example of printing list items on separate lines using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=3ZdGucbtXgI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list of items +suits = ["Heart", "Club", "Diamond"] + +# To output each item on a separate line we can put a * in front of the list +# variable name to pass each item individually to print, i.e. print will +# be called like this: print("Heart", "Club", "Diamond") +# +# We can then use the keyword argument 'sep' to alter which character separates +# the arguments of print() when they are output, which by default is a space +# character. We pass "\n" which is the newline character, so that after each +# item is output the newline character will be output so that each item +# will output on a separate newline. + +print(*suits, sep="\n") \ No newline at end of file From 5f15ea2599db782c8d5011ac9dfef83d3ee53942 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 16 Oct 2023 13:21:53 -0400 Subject: [PATCH 011/101] shuffle a deck of cards --- shuffle_deck_of_cards.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 shuffle_deck_of_cards.py diff --git a/shuffle_deck_of_cards.py b/shuffle_deck_of_cards.py new file mode 100644 index 0000000..9c712be --- /dev/null +++ b/shuffle_deck_of_cards.py @@ -0,0 +1,43 @@ +################################################################################ +# +# Program: Shuffle A Deck Of Cards +# +# Description: Example of creating and shuffling a deck of cards using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=9Lh4PAN1HsA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We'll represent a deck of cards using a list of tuples, where each tuple +# contains a suit and rank. +# +# See Deck Of Cards: https://en.wikipedia.org/wiki/Standard_52-card_deck + + +# Import the random module so we can use the shuffle() function to shuffle the +# deck of cards. +import random + +# A standard deck of card has 4 suits. +suits = ['Heart', 'Diamond', 'Club', 'Spade'] + +# And each suit has 13 cards of each rank. +ranks = ['Ace', '2', '3', '4', '5', '6', '7', + '8', '9', '10', 'Jack', 'Queen', 'King'] + +# Use a list comprehension to produce a list of tuples with 13 cards of each +# rank FOR each suit, for 52 cards total. +deck = [(rank, suit) for suit in suits + for rank in ranks] + +# The shuffle function from the random module will randomly rearrange the items +# of a list, so by passing deck we will "shuffle the deck". +random.shuffle(deck) + +# Output each item in the deck list. We pass the list using *deck so that each +# item in the list is passed to print() as an individual argument, and then +# sep="\n" will separate each value output by print by a newline character to +# output each "card" on a new line. +print(*deck, sep="\n") \ No newline at end of file From 75f3b82b7101da0afa3c261b3616de06e43f8625 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:57:47 -0400 Subject: [PATCH 012/101] __str__ method for humand-readable string example --- __str__method.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 __str__method.py diff --git a/__str__method.py b/__str__method.py new file mode 100644 index 0000000..10b7af9 --- /dev/null +++ b/__str__method.py @@ -0,0 +1,49 @@ +################################################################################ +# +# Program: __str__ Method Example +# +# Description: Example of using the __str__ method in Python which allows us to +# define an informal human-readable string representation of an object. +# +# YouTube Lesson: https://www.youtube.com/watch?v=GKFwko0byM0 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A simple class to represent students +class Student: + + # Initializes the attributes name and grade to the parameter values + def __init__(self, name, grade): + self.name = name + self.grade = grade + + # If we define the magic method (i.e. dunder method) __str__ and have it + # return a string, it is this string that will be used to represent the + # object with the built-in print(), str() and format() functions. Here + # we simply return the two attributes values in a string, using a f-string. + def __str__(self): + return f"{self.name} ({self.grade})" + + # Notably there is a similar function called __repr__ that is intended to + # return a formal and complete representation of the object suitable for + # debugging and developing purposes + # + # def __repr__(self): + + +# Create a Student object +mary = Student("Mary", "A+") + +# When we output the object with print the __str__ method we define will be +# called and it is the string returned by this method that will be output. +# If we did not define __str__ the default string essentially will be the +# object type + address. +print(mary) + +# Our __str__ method will also be used if we call the built in str() function +mary_string = str(mary) + +# If we output this string it will be the same as the string output by print() +print(mary_string) \ No newline at end of file From 9d22ea4599f1775ad1117a83a13a628e05687a07 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 26 Oct 2023 00:40:50 -0400 Subject: [PATCH 013/101] __repr__ method to convert object to string --- __repr__method.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 __repr__method.py diff --git a/__repr__method.py b/__repr__method.py new file mode 100644 index 0000000..37af31a --- /dev/null +++ b/__repr__method.py @@ -0,0 +1,55 @@ +################################################################################ +# +# Program: __repr__ Method Example +# +# Description: Example of using the __repr__ magic method (i.e. dunder method) +# in Python to represent an object as a string in a formal, complete way that is +# suitable for debugging or programming purposes. +# +# YouTube Lesson: https://www.youtube.com/watch?v=LV27ZMm8TWk +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A simple class for representing students +class Student: + + # Student objects will have name and grade attributes + def __init__(self, name, grade): + self.name = name + self.grade = grade + + # The __repr__ method is expected to return a string representation of the + # object that is suitable for programming or debugging purposes. Here we + # use an f-string to build and return a string that contains the object + # member variable values with the format: Student('name','grade') + def __repr__(self): + return f"Student('{self.name}','{self.grade}')" + + # There is a similar magic method called __str__ that is intended for + # representing the object as a string in a more informal and human-readable + # way. We could also define this method. + # + # def __str__(self): + + +# Create a Student object +mary = Student("Mary", "A+") + +# The built-in repr() function will call our __repr__ method above and return +# the string it produces, which we output... +mary_string = repr(mary) +print(mary_string) + +# The string returned be our __repr__ method can be evaluated as Python code +# using the built in eval() function, which will create a Student object. +# We assign the resulting object to mary_object and verify it's type and +# output the attribute name. +mary_object = eval(mary_string) +print(type(mary_object)) +print(mary_object.name) + +# If we do not define an __str__ method, the print() function will use our +# __repr__ method to convert mary_object to a string to be printed. +print(mary_object) \ No newline at end of file From 9b253c21c5347a0d552a2a75b3a2eb99b49fdcbf Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 28 Oct 2023 08:59:35 -0400 Subject: [PATCH 014/101] __add__ method example: + operator overloading --- __add__method.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 __add__method.py diff --git a/__add__method.py b/__add__method.py new file mode 100644 index 0000000..286e505 --- /dev/null +++ b/__add__method.py @@ -0,0 +1,43 @@ +################################################################################ +# +# Program: __add__ Method Example +# +# Description: Example of using the __add__ magic method (i.e. dunder method) in +# Python to define how the addition operator (+) should behave for a type of +# object (i.e. operator overloading). +# +# YouTube Lesson: https://www.youtube.com/watch?v=LlZ-BcrCBZY +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A simple class for representing bank accounts with a balance +class BankAccount: + + # Set the balance attribute to some initial deposit amount + def __init__(self, initial_deposit): + self.balance = initial_deposit + + # Output the balance + def print_balance(self): + print("Balance:", self.balance) + + # Defines how the addition operator (+) will behave for BankAccount + # objects, where if we have account1 + account2, this method will be + # called with "self" set to account1 and "other" set to account2. We + # then have the method return a new BankAccount object with the combined + # balance of both bank accounts (exactly what we have the __add__method + # do is up to us, but this is sensible behaviour). + def __add__(self, other): + total = self.balance + other.balance + return BankAccount(total) + +# Create two bank account objects together +account1 = BankAccount(1000) +account2 = BankAccount(2000) + +# After adding the two bank accounts we'll find the newly created and returned +# BankAccount object has the combined balance of both BankAccount objects. +new_account = account1 + account2 +new_account.print_balance() \ No newline at end of file From 199ac9783befb12deb5b296ca1412558b9da5954 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:20:25 -0400 Subject: [PATCH 015/101] bubble sort implementation --- bubble_sort.py | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 bubble_sort.py diff --git a/bubble_sort.py b/bubble_sort.py new file mode 100644 index 0000000..f087fd1 --- /dev/null +++ b/bubble_sort.py @@ -0,0 +1,63 @@ +################################################################################ +# +# Program: Bubble Sort +# +# Description: An implementation of the Bubble Sort algorithm in Python. See the +# wikipedia article on Bubble Sort: https://en.wikipedia.org/wiki/Bubble_sort +# +# YouTube Lesson: https://www.youtube.com/watch?v=SqUpPwiTSak +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Sorts the list 'a' using the bubble sort algorithm +def bubble_sort(a): + + # Find the length of the list + length = len(a) + + # Perform up to length-1 number of "passes" through the list + for i in range(0,length-1): + + # We can perform less passes if the list happens to be sorted with + # a fewer number of passes. We'll use swapped to help us detect + # whether a swap occurred. If no swap occurs during a pass, the list + # must already be sorted. + swapped = False + + # Make a "pass" through the list, compare the item at each index to + # the item in the adjacent index, and swap them if they are not + # in ascending order. We set swapped to True if a swap occurs, which + # tells us the list was not yet sorted at the beginning of this pass. + # We initially have the counter variable go from 0,length-2, the + # 2nd last index of the list. This is because the last item in the + # list has no item at j+1. With each pass through the list the + # next largest item in the list will have been shifted down to + # its correct position in the sorted list. i.e. after the first pass + # through the list the largest item will be in the last index of + # the list, after the second pass through the list the second + # largest item will be in the second last index of the list, and + # so on. We don't need to perform any comparisons with the these + # last items because we already know they are in the correct positino. + # So we have length - i - 1, subtracting i, for the end of the + # range, so that we go one less item deep into the list each time + # with each pass as i goes from 0,1,2,... and on in the outer loop. + for j in range(0,length-i-1): + if a[j] > a[j+1]: + a[j], a[j+1] = a[j+1], a[j] + swapped = True + + # If no swap occurs, we have discovered the list is now sorted and + # break to stop the outer loop early as no more passes are required. + if not swapped: + break + +# A test list for bubble sort to sort +a = [6,5,3,1,8,7,2,4] + +# Call the function to sort 'a' +bubble_sort(a) + +# Output the now sorted list +print(a) \ No newline at end of file From 1d8c9b15384ebf988e9b29363f6cdc5d4d1102e4 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 5 Nov 2023 23:51:19 -0500 Subject: [PATCH 016/101] __radd__ method example --- __radd__method.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 __radd__method.py diff --git a/__radd__method.py b/__radd__method.py new file mode 100644 index 0000000..91eed72 --- /dev/null +++ b/__radd__method.py @@ -0,0 +1,84 @@ +################################################################################ +# +# Program: __radd__ Method Example +# +# Description: An example of using the __radd__ magic method (i.e. dunder +# method) in Python to define how the addition (+) operator should behave for +# a type of object (i.e. operator overloading) when the object is the right +# operand of the addition. +# +# YouTube Lesson: https://www.youtube.com/watch?v=UkjKj4AmNhc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We'll use Number to check if the other + operand is a type of number in Python +from numbers import Number + +# Represents bank accounts +class BankAccount: + + # Bank accounts have a balance attribute set to an initial balance + def __init__(self, initial_balance): + self.balance = initial_balance + + # Defines how BankAccount objects should behave with the + operator, both + # in the case that both operands are BankAccount objects AND in the case + # that the BankAccount is the left operand and a type of number is the + # right operand. The parameter self is the left operand of the + # addition operator, and other is the right operand of the addition + # operator. In the case of adding together two BankAccount objects + # we return a new BankAccount object with the combined balance, in the + # case of a BankAccount object added together with a number we return + # a new BankAccount object with the sum of the number and the BankAccount + # operand's balance as the balance of the new BankAccount object. + def __add__(self, other): + # If the right operand is a type of number, we calculate a new total + # balance by adding the left operand BankAccount balance to the number. + if (isinstance(other, Number)): + total = self.balance + other + # If both operands are BankAccount objects we add both balances to + # produce the new total + else: + total = self.balance + other.balance + + # We return a new BankAccount object with the new total. + return BankAccount(total) + + # The __add__ method will be called if we have: + # + # BankAccount + BankAcccount + # + # OR + # + # BankAccount + Number (where Number is some type of number in Python) + # + # But if we have... + # + # Number + BankAccount + # + # then __add__ will NOT be called. Instead __radd__ will be called + # with self set to the right BankAccount operand and other set to + # Number. Because we want + to be commutative (i.e. a + b == b + a) we + # can return the result of calling the __add__ method with other/Number + # as an argument. + # + # Note that in general when we have left_operand + right_operand the + # __radd__ method of right_operand will be called when either: + # + # 1) the __add__ method is not defined for left_operand + # 2) the __add__ method returns NotImplemented + # + def __radd__(self,other): + return self.__add__(other) + +# Create a bank account object +account1 = BankAccount(1000) + +# Add the bank account to a number, with the bank account as the right operand, +# which will cause __radd__ to be called +new_account = 4000.50 + account1 + +# Output the resulting BankAccount object's balance +print(new_account.balance) \ No newline at end of file From ffdb6db053a38fc9188eb36164b59ad1e7a1262d Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 6 Nov 2023 13:24:26 -0500 Subject: [PATCH 017/101] multiplication operator overloading example --- __mul__and__rmul__.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 __mul__and__rmul__.py diff --git a/__mul__and__rmul__.py b/__mul__and__rmul__.py new file mode 100644 index 0000000..ee85681 --- /dev/null +++ b/__mul__and__rmul__.py @@ -0,0 +1,31 @@ +################################################################################ +# +# Program: __mul__ and __rmul__ Method Examples +# +# Description: Example of using the __mul__ and __rmul__ magic methods (i.e. +# dunder methods) in Python to define how the addition operator (*) should +# behave for a type of object (i.e. operator overloading). +# +# YouTube Lesson: https://www.youtube.com/watch?v=wYw9r3JIkY8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +class Population: + + def __init__(self, initial_count): + self.count = initial_count + + def __mul__(self, other): + if (isinstance(other, Number)): + return Population(self.count * other) + return Population(self.count * other.count) + + def __rmul__(self, other): + return self.__mul__(other) + +population1 = Population(100) + +new_population = 5.5 * population1 +print(new_population.count) \ No newline at end of file From 21bd5e334664c6c28fd16c52d15ee863a75e516b Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:38:42 -0500 Subject: [PATCH 018/101] multiplication operator overloading example --- __mul__and__rmul__.py | 66 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/__mul__and__rmul__.py b/__mul__and__rmul__.py index ee85681..3f4b084 100644 --- a/__mul__and__rmul__.py +++ b/__mul__and__rmul__.py @@ -12,20 +12,82 @@ # ################################################################################ +# A simple class to represent a population class Population: + # When population objects are initialized they will have a count attribute + # initialized to some initial count def __init__(self, initial_count): self.count = initial_count + # This function is called when we have either: + # + # PopulationObject * PopulationObject + # + # OR + # + # PopulationObject * NumberObject + # + # Where NumberObject is some type of number in Python. The function + # supports both cases of the right operand being either a Population-type + # object or some kind of number type object in Python. + # + # We define how the multiplication operator should behave in this case + # by returning a new Population object. In the case of multiplying + # two Population objects we set the new Population object's count to + # the product of the two Population object's counts. In the case of + # multiplying a Population object by a number, we set the new Population + # object's count to the product of the Population operand object's count + # and the number. + # + # The isinstance() function will return True if other is a type of number + # in Python. + # def __mul__(self, other): if (isinstance(other, Number)): return Population(self.count * other) return Population(self.count * other.count) + # In the case that we have... + # + # NumberObject * PopulationObject + # + # Then the __mul__ method of the number type object will not know how to + # work with a Population type object, and the below __rmul__ method will + # be called instead with self set to the right PopulationObject and other + # set to NumberObject. Because we want * to be commutative + # (i.e. a * b == b * a) we can return the result of calling the __mul__ + # method with other/NumberObject as an argument. + # + # Note that in general when we have left_operand * right_operand the + # __rmul__ method of right_operand will be called when either: + # + # 1) the __mul__ method is not defined for left_operand + # 2) the __mul__ method returns NotImplemented + # def __rmul__(self, other): return self.__mul__(other) +# Create two Population objects population1 = Population(100) - +population2 = Population(5) + +# This would result in a call to __mul__ and a new Population object with a +# count of 500... +# +# new_population = population1 * population2 + +# This would result in a call to __mul__ and a new Population object with a +# count of 500, but this time 'other' will be an instance of type Number +# because 5 is an int value (which is a type of Number in Python). +# +# new_population = population1 * 5 + +# This would result in a call to __rmul__ because the Float object 5.5. does +# not have a __mul__ method that supports working with a Population object +# as a right operand. +# new_population = 5.5 * population1 -print(new_population.count) \ No newline at end of file + +# Output the count of the new Population object... +print(new_population.count) From 5c6774e6b15bba1dacbdec65292727604c433e77 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 7 Nov 2023 23:32:18 -0500 Subject: [PATCH 019/101] reverse a list without using reverse() method --- reverse_a_list.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 reverse_a_list.py diff --git a/reverse_a_list.py b/reverse_a_list.py new file mode 100644 index 0000000..aa9fc81 --- /dev/null +++ b/reverse_a_list.py @@ -0,0 +1,43 @@ +################################################################################ +# +# Program: Reverse A List Without Using reverse() +# +# Description: An example of how to reverse a list in Python without using the +# built-in .reverse() method. +# +# YouTube Lesson: https://www.youtube.com/watch?v=byxdI22yt_E +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list of numbers for test purposes +numbers = [5,6,7,8,9] + +# We could call the built-in reverse() method to reverse the list +# numbers.reverse() + +# There are many ways to "manually" reverse a list. The below loop will +# continually remove the last item in the list and insert it into the +# list at the next index in the list going from 0,1,2,... up until (but not +# including) the last index in the list because that item will be in its +# correct position at that point. The loop will run with i set to the +# indexes 0,1,2,...len(numbers)-2, and we use this index to perform the +# insert. We use the built-in .insert() method to insert the item and +# the .pop() method which removes and returns the last item in the list. +for i in range(len(numbers) - 1): + numbers.insert(i, numbers.pop()) + + # We could output i and the numbers list to see how the algorithm works + # print(i, numbers) + +# We could also use the slicing operator to reverse a list, this application +# of the operator will create a new list made up of the items of numbers +# going from the last item in the list to the first item in the list and +# including each item in that order in the new list. We store the resulting +# new list back into numbers so that numbers now stores (references) the +# reversed list. +numbers = numbers[::-1] + +# Output the now reversed list +print(numbers) \ No newline at end of file From 79c37a4c1085c0eb788ccbeea85dd2035d8befe1 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:59:03 -0500 Subject: [PATCH 020/101] sum the first N natural numbers using recursion --- sum_natural_numbers_recursive.py | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 sum_natural_numbers_recursive.py diff --git a/sum_natural_numbers_recursive.py b/sum_natural_numbers_recursive.py new file mode 100644 index 0000000..c9ec8a3 --- /dev/null +++ b/sum_natural_numbers_recursive.py @@ -0,0 +1,58 @@ +################################################################################ +# +# Program: Sum The First N Natural Numbers Using Recursion +# +# Description: Program to sum the first N natural numbers using recursion in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=skUMJwu1-aQ +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The natural numbers are the numbers 1,2,3,... +# +# So the first 5 natural numbers and their sum are 5 + 4 + 3 + 2 + 1 = 15 +# +# A recursive function is a function that calls itself to solve a problem, +# typically solving part of the problem and calling itself with a smaller +# version of the remaining problem to be solved. +# +# The below function carries out the chain of addition operations required +# to produce the sum, by returning 'n' the current natural number + the +# result of calling the function with 'n-1'. This will result in a chain +# of additions as each function call returns 5 + 4 + 3 + ..., etc. +# +# We call the "return n + sum(n-1)" case the recursive case or recursive step. +# Eventually recursion (the function calling itself) needs to stop. We stop +# recursion and simply return 1 once n == 1, as 1 is the final natural +# number. We call this case where recursion stops the base case or the +# base step. + +# Returns the sum of the first n natural numbers using recursion +def sum(n): + if n == 1: + return 1 + return n + sum(n-1) + +# Test the function +print(sum(5)) + +# We can visualize the series of function calls that will occur like this... +# +# sum(5) -> return 5 + sum(4) +# sum(4) -> return 4 + sum(3) +# sum(3) -> return 3 + sum(2) +# sum(2) -> return 2 + sum(1) +# sum(1) -> return 1 (special base case where recursion stops) + +# We can then work backwards from the bottom to the top, replacing each +# function call with the relevant return value, and we see how the sum(5) +# will return 15... +# +# sum(5) -> return 5 + 10 -> return 15 +# sum(4) -> return 4 + 6 -> return 10 +# sum(3) -> return 3 + 3 -> return 6 +# sum(2) -> return 2 + 1 -> return 3 +# sum(1) -> return 1 \ No newline at end of file From a32b65a1a1fc625658a1441fe2fad2b68a187246 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:39:47 -0500 Subject: [PATCH 021/101] reverse a list using recursion --- reverse_a_list_recursive.py | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 reverse_a_list_recursive.py diff --git a/reverse_a_list_recursive.py b/reverse_a_list_recursive.py new file mode 100644 index 0000000..e6f6334 --- /dev/null +++ b/reverse_a_list_recursive.py @@ -0,0 +1,52 @@ +################################################################################ +# +# Program: Reverse A List Using Recursion +# +# Description: Program to reverse a list using recursion in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=UiDzexaMY4Y +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The below function works using recursion by removing the last item in the +# list, and concatenating a list containing only that item with the list +# returned by calling the reverse function with the remaining portion of the +# list... +# +# return [lst.pop()] + reverse(lst) +# +# We call this the recursive step as the function calls itself. +# +# So if reverse is called with [5,6,7,8,9] the function will then return: +# +# [9] + reverse([5,6,7,8]) +# +# And then the NEXT call to reverse will give us... +# +# [9] + [8] + reverse([5,6,7]) +# +# And we can see how the list will be reversed one item at a time! We stop +# the function from calling itself further when reverse is passed the +# empty list with... +# +# if lst == []: +# return [] +# +# We call this the base case because this is when recursion stops. So all +# together we will have: +# +# [9] + [8] + [7] + [6] + [5] + [] which results in the list [9,8,7,6,5]. + +# Returns a reversed version of the list lst using recursion +def reverse(lst): + if lst == []: + return [] + return [lst.pop()] + reverse(lst) + +# Test list +numbers = [5,6,7,8,9] + +# Output the reversed list returned by the reverse() function +print(reverse(numbers)) \ No newline at end of file From ab77e34987f873b76990be8232034e31dc57f117 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:43:30 -0500 Subject: [PATCH 022/101] count the digits in an integer using recursion --- count_digits_recursive.py | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 count_digits_recursive.py diff --git a/count_digits_recursive.py b/count_digits_recursive.py new file mode 100644 index 0000000..3ecbc74 --- /dev/null +++ b/count_digits_recursive.py @@ -0,0 +1,59 @@ +################################################################################ +# +# Program: Count The Digits In An Integer Using Recursion +# +# Description: Program to count the digits in an integer using recursion in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=CTqMbOTGnDI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We can find the number of digits in an integer by dividing the integer by +# 10, and taking the quotient and dividing it by 10, and continuing this process +# until the quotient is 0. The number of divisions that it takes for the +# resulting quotient to reach 0 is the number of digits in the number. +# +# So for example with 472: +# +# 472 / 10 = 47 remainder 2 +# 47 / 10 = 4 remainder 7 +# 4 / 10 = 0 remainder 4 +# +# And because we have 3 division operations this tells us the number has 3 +# digits. +# +# To solve a problem using a recursion we will create a recursive function, +# i.e. a function which calls itself. A recursive function will typically +# solve part of the problem to be solved and then call itself with a smaller +# portion of the remaining same problem to be solved. We have our recursive +# function count one digit each time it is called, and call itself with the +# quotient after diving by 10: +# +# return 1 + count_digits(number // 10) +# +# We add 1 to the count of the number of digits of number // 10 as returned by +# calling the function, in order to return the total number of digits in the +# number. Note that // is integer division in Python and will return the +# quotient of the number divided by 10. We call this the recursive step or +# recursive case, where the function calls itself. +# +# We stop recursion when the number divided by 10 results in a quotient of +# 0, as this tells us we have counted the last digit and we simply return 1. +# +# if number // 10 == 0: +# return 1 +# +# We call this step where recursion stops the base case or the base step. + + +# Returns the number of digits in the integer 'number' using recursion +def count_digits(number): + if number // 10 == 0: + return 1 + return 1 + count_digits(number // 10) + +# Test the function +print(count_digits(472)) \ No newline at end of file From 0d7387f0b19c45ff0e62ee8723f218a7b5813c36 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 11 Nov 2023 23:25:50 -0500 Subject: [PATCH 023/101] sum the digits of an integer using recursion --- sum_digits_recursive.py | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 sum_digits_recursive.py diff --git a/sum_digits_recursive.py b/sum_digits_recursive.py new file mode 100644 index 0000000..12aad40 --- /dev/null +++ b/sum_digits_recursive.py @@ -0,0 +1,64 @@ +################################################################################ +# +# Program: Sum The Digits In An Integer Using Recursion +# +# Description: Program to sum the digits in an integer using recursion in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=GktKLZYX8v8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We can find the sum of the digits in an integer by dividing the integer by +# 10, and taking the quotient and dividing it by 10, and continuing this process +# until the quotient is 0. The remainder of each division operation that it +# takes for the resulting quotient to reach 0 gives us each digit in the number. +# +# So for example with 472: +# +# 472 / 10 = 47 remainder 2 +# 47 / 10 = 4 remainder 7 +# 4 / 10 = 0 remainder 4 +# +# And the sum of the remainder 4 + 7 + 2 = 13 is the sum of the digits in +# 472 as 4, 7, and 2 are the digits of the integer. +# +# In Python the integer division operation // give us the quotient of a +# division operation and the modulus operator % gives us the remainder. +# +# To solve a problem using recursion we will create a recursive function, +# i.e. a function which calls itself. A recursive function will typically +# solve part of the problem to be solved and then call itself with a smaller +# portion of the remaining same problem to be solved. We have our recursive +# function sum one digit each time it is called, and call itself with the +# quotient after diving by 10: +# +# remainder = number % 10 +# ... +# return 1 + sum_digits(number // 10) +# +# We return the result of adding the remainder/digit to the sum of the digits +# in number // 10 (i.e. the sum of the remaining digits in the number) as +# given by calling the function sum_digits again with number // 10. We call +# this the recursive step or recursive case, where the function calls itself. +# +# We stop recursion when the number divided by 10 results in a quotient of +# 0, as this tells us we have found the last digit, and we simply return +# that digit (remainder). +# +# if number // 10 == 0: +# return remainder +# +# We call this step where recursion stops the base case or the base step. + +# Returns the sum of the digits in the integer value number +def sum_digits(number): + remainder = number % 10 + if number // 10 == 0: + return remainder + return remainder + sum_digits(number // 10) + +# Test the function +print(sum_digits(472)) \ No newline at end of file From 6a079f8b54c9b1e2478623fd6f326982d0383a6a Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:11:45 -0500 Subject: [PATCH 024/101] __len__ magic method (duner method) example --- __len__method.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 __len__method.py diff --git a/__len__method.py b/__len__method.py new file mode 100644 index 0000000..328789b --- /dev/null +++ b/__len__method.py @@ -0,0 +1,61 @@ +################################################################################ +# +# Program: __len__ Magic Method +# +# Description: Example of using the __len__ magic method (i.e. dunder method) +# in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=bGGXE0D41Nw +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A simple class to represent orders +class Order: + + # Orders will have an items attribute set to a list of items in the order + def __init__(self, items): + self.__items = items + + # If we supply a definition for the __len__ dunder method, then when objects + # of this class type are passed to the built-in len() function, this method + # will be called. We can define this function however it makes sense for + # the type of object we're defining, but the return value does need to be + # an integer >= 0. Here we return the length of the items attribute list. + def __len__(self): + return len(self.__items) + + +# Create an Order object with 3 items. +order = Order(["Pizza", "Pasta", "Salad"]) + +# We could create an object with 0 items like this. +# order = Order([]) + +# The built-in len() function will return 3 if we call it with len([1,2,3]), +# but unless if we define a __len__ magic method as above it will not work +# for new object types we define. + +# When we call len() and pass it the Order object the __len__ magic method is +# called and 3 will be returned. We can output the returned length which we +# stored into order_length. +order_length = len(order) +print("Length:", order_length) + +# Objects will evaluate to a boolean value True or False when used in situations +# like if-statement conditions. If no __bool__ AND no __len__ magic methods are +# defined, the object will default to the value of True. If a __bool__ magic +# method is defined, this method will be called to return either True or False. +# If no __bool__ magic method is defined BUT a __len__ magic method IS defined +# then this method will be called, and if returns 0, the object will evaluate +# to False, otherwise if it returns a number greater than 0, the object will +# evaluate to False. +# +# So if we have an Order object with 3 items we'll get True below. If we +# instead had an Order object with 0 items we would get False below. +# +if order: + print("order is True") +else: + print("order is False") \ No newline at end of file From 24678203f4ec3dee123034c86600ee366ee5ef99 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:22:25 -0500 Subject: [PATCH 025/101] check if two strings are anagrams --- anagram_checker.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 anagram_checker.py diff --git a/anagram_checker.py b/anagram_checker.py new file mode 100644 index 0000000..e8bc30e --- /dev/null +++ b/anagram_checker.py @@ -0,0 +1,39 @@ +################################################################################ +# +# Program: Check If Two Strings Are Anagrams +# +# Description: Check if two strings are anagrams using Python, where two strings +# are considered anagrams if they contain the same letters: +# https://en.wikipedia.org/wiki/Anagram +# +# YouTube Lesson: https://www.youtube.com/watch?v=Zpsw6YCHyDs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns True if s1 and s2 are anagrams, and False otherwise +def check_anagram(s1,s2): + s1_list = sorted(s1.lower().replace(" ", "")) + s2_list = sorted(s2.lower().replace(" ", "")) + return s1_list == s2_list + +# Two strings that are anagrams +string1 = "Tom Marvolo Riddle" +string2 = "I am Lord Voldemort" + +# The sorted() function returns an alphabetically sorted list of the characters +# in a string. The above function works by first removing all space characters +# in the strings using replace(), and setting all characters to lowercase using +# lower(). This ensures that space characters and the capitalization of the +# letters do not affect whether strings are considered anagrams or not. We then +# use sorted() on both strings, and if the two strings are anagrams containing +# the same letters, then the two lists should be identical. So we check the +# lists for equality using == as the check to see if the two strings are +# anagrams or not. +# +print( sorted(string1) ) +print( sorted(string2) ) + +# Check if the two strings are anagrams and output the result +print( check_anagram(string1, string2) ) \ No newline at end of file From 8fa1e9bbf201987819de3e122e12a0c70204209d Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 1 Dec 2023 23:09:22 -0500 Subject: [PATCH 026/101] check if all the characters in a string are unique --- check_string_chars_unique.py | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 check_string_chars_unique.py diff --git a/check_string_chars_unique.py b/check_string_chars_unique.py new file mode 100644 index 0000000..4b2e51c --- /dev/null +++ b/check_string_chars_unique.py @@ -0,0 +1,39 @@ +################################################################################ +# +# Program: Check If All String Characters Are Unique +# +# Description: Check if all the characters in a string are unique using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=HEhdM7zdy68 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns true if all characters in the string are unique and false otherwise +def check_unique(string): + + # Keeps track of the unique characters found in the string "so far" + unique_characters = [] + + # Loop through the string one character at a time and check to see if the + # character was previously encountered (i.e. is the character NOT unique) + # by checking to see if it's already in the unique_characters list. If it + # IS already in the unique characters list, we can return False as we have + # established not all characters in the string are unique. Otherwise this + # character is a NEW unique character so we append it to the + # unique_characters list. + # + for character in string: + if character in unique_characters: + return False + else: + unique_characters.append(character) + + # If we go through all characters in the string and all of them are unique + # we can return True + return True + +# Test out the function +test = "abcd" +print( check_unique(test) ) \ No newline at end of file From 3be10cc1db6bfc7a6ca2e531a5ee7d94822cc113 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 3 Dec 2023 00:19:59 -0500 Subject: [PATCH 027/101] word guessing game (similar to hangman) --- word_guessing_game.py | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 word_guessing_game.py diff --git a/word_guessing_game.py b/word_guessing_game.py new file mode 100644 index 0000000..7eea1ec --- /dev/null +++ b/word_guessing_game.py @@ -0,0 +1,116 @@ +################################################################################ +# +# Program: Word Guessing Game (Like Hangman) +# +# Description: A word guessing game similar to "hangman" using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=N_6YIClAor0 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import random + +# Returns a randomly selected word +def choose_word(): + words = ["python", "coding", "portfolio", "courses", \ + "programming", "code", "data", "visual", "studio"] + + # choice() returns a randomly selected word from words list + return random.choice(words) + +# Returns a string representing the status of the word to guess with respect +# to the guess_letters so far. i.e. if the word to guess is "python" and +# the guessed_letters so far are ["y", "t"] then _yt__ would the status of +# the word to guess. +def word_status(word, guessed_letters): + + # Loop through the word one letter at at time, concatenating the letter + # to the display string if it IS a guess_letter and _ if it is not + display = "" + for letter in word: + if letter in guessed_letters: + display += letter + else: + display += "_" + + return display + +# Runs the word guessing game +def word_guessing_game(): + + # Initial game status: pick a secret word, no guess letters yet, and give + # the player 7 attempts to guess a correct letter + secret_word = choose_word() + guessed_letters = [] + attempts = 7 + + # Output the game title and initial status of the word to guess which will + # be all _ characters BUT this will tell the player how many letters are in + # the word total. + print("Word Guessing Game") + print("******************") + print("Secret Word:", word_status(secret_word, guessed_letters)) + + # Continue the game so long as the player has attempts remaining + while attempts > 0: + + # Prompt the user to enter their next guess/letter, use lower() to + # make it lowercase regardless of what case the player enters. This + # is just so when checking if the letter is in the word we don't run + # recognize they guessed correctly due to the player using uppercase + # comparing against words that are lowercase. + guess = input("Guess A Letter: ").lower() + + # If the length of the string entered is not 1 and all the characters + # in the string are not letters, output an error message, and use + # continue to skip execution of the rest of the loop body. + if len(guess) != 1 or not guess.isalpha(): + print("You must enter a single letter.") + continue + + # Also output an error message and skip the remainder of the loop body + # if the guessed letter is a previously guessed letter. + if guess in guessed_letters: + print("You already guessed that letter.") + continue + + # Otherwise if it is a new single letter that was guessed add it to the + # list of guessed letters. + guessed_letters.append(guess) + + # If the guessed letter is NOT in the word to be guessed the player + # loses an attempt and we output a message informing them of this + # and the number of remaining attempts they have left. + if guess not in secret_word: + attempts -= 1 + print(f"No letter '{guess}' occurs in the word.") + print(f"You have {attempts} attempts remaining.") + # Otherwise if the guessed letter IS in the word we can output the + # number of time it occurs. + else: + occurrences = secret_word.count(guess) + print(f"Letter '{guess}' occurs {occurrences} times.") + + # Output the new current status of the word + current_status = word_status(secret_word, guessed_letters) + print("Secret Word:", current_status) + + # If there are no remaining _ characters in the status of the word this + # means the player has guessed all the letters and has won the game, we + # output a congratulations message and use break to stop the loop (and + # end the game). + if "_" not in current_status: + print("Congratulations! You guessed the word.") + break + + # If the player runs out of attempts and there is an _ character in the + # status of the word this means the user failed to guess all the letters + # before running out of attempts. In this case we just inform the user + # of this and output what the word to be guessed was. + if "_" in current_status: + print(f"You ran out of attempts! The word was: {secret_word}") + +# Call the function to play the game +word_guessing_game() \ No newline at end of file From 2944e4dd97da8b957e413975e33b3766c079fb09 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:09:38 -0500 Subject: [PATCH 028/101] generate a list containing the Fibonacci sequence --- fib_list.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 fib_list.py diff --git a/fib_list.py b/fib_list.py new file mode 100644 index 0000000..ed5d9ae --- /dev/null +++ b/fib_list.py @@ -0,0 +1,50 @@ +################################################################################ +# +# Program: Generate A List Containing The Fibonacci Sequence +# +# Description: Generate a list containing the Fibonacci Sequence numbers in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Dvk7qqcU7QI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The Fibonacci sequence is as follows: +# +# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... +# +# The first two numbers in the sequence are 0 and 1, with each additional +# number in the sequence defined as the sum of the previous two. +# +# F0 = 0 +# F1 = 1 +# Fn = Fn-1 + Fn-2 +# +# See: https://en.wikipedia.org/wiki/Fibonacci_sequence + +# Returns a list containing the first n numbers of the Fibonacci sequence +def create_fib_sequence(n): + + # n <= 0 does not make sense, we can return None for this (or []) + if n <= 0: + return None + # Return a list containing the first number of the Fibonacci sequence + elif n == 1: + return [0] + else: + # Begin with a list of the 2 Fibonacci sequence numbers + fibs = [0,1] + + # This loop will execute n-2 times, and each time we append the next + # number in the Fibonacci sequence by summing the LAST two Fibonacci + # sequence numbers in the list. + for i in range(2,n): + fibs.append( fibs[-1] + fibs[-2] ) + + # Return the generated list + return fibs + +# Output the list containing the first 10 Fibonacci numbers +print( create_fib_sequence(10) ) \ No newline at end of file From bd9f4a751068fcf4383ea0b0fea379f04b35a113 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 5 Dec 2023 23:57:49 -0500 Subject: [PATCH 029/101] all() built-in function examples --- all.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 all.py diff --git a/all.py b/all.py new file mode 100644 index 0000000..ace0e31 --- /dev/null +++ b/all.py @@ -0,0 +1,61 @@ +################################################################################ +# +# Program: all() Built-In Function Examples +# +# Description: Examples of using the built-in all() function in Python to check +# if all the values in an iterable object are true. +# +# YouTube Lesson: https://www.youtube.com/watch?v=E2j4QjDyXzs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The all() function built-in to Python returns True if all the items of an +# iterable object such as a list or set are true, so the below call to all() +# will return True... +print(all( [True, True, True] )) + +# With a False item in the iterable all() will return False +print(all( [True, True, False] )) + +# all() will work with items that evaluate to True or False, so because "abc" +# evaluates to True all() will return True +print(all( [True, True, "abc"] )) + +# "" evaluates to False so all() will return False +print(all( [True, True, ""] )) + +# all() will return True for empty iterable objects such as the empty list +print(all( [] )) + +# all() will work with iterables of all types such as a set containing 1,2,3 +# which all evaluate to True (so all() will return True) +print(all( {1,2,3} )) + +# 0 evaluates to False so all() will return False +print(all( {1,2,0} )) + +# In the case of a dictionary iterable object all() will check if the keys +# are all true, so with keys 1 and 2 being true all() returns True below +print(all( {1: False, 2: False} )) + +# But with the key 0 being false all() will return False below +print(all( {1: False, 0: False} )) + +# One good use case of all() comes from using it with list comprehensions. Say +# we have a list of strings and we wish to check if all the strings start with +# "appl". We could use a loop structure to go through and check if each item +# starts with "appl", or we could use a single line of code using all() and +# a list comprehension instead. +strings = ["apple", "against", "application"] + +# The list comprehension uses the startswith() method with each string in the +# above list to produce a list of True/False values depending on whether each +# string starts with "appl". We then use all() to verify if ALL the strings +# start with "appl" (which will be the case if all list items are True in the +# list produced by the list comprehension). +if all( [s.startswith("appl") for s in strings] ): + print("all the items begin with 'appl'") +else: + print("all the items do not begin with 'appl'") \ No newline at end of file From a559b20dc7c0f7b6e034a75c7238dff9a098dada Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 6 Dec 2023 23:25:10 -0500 Subject: [PATCH 030/101] any built-in function examples --- any.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 any.py diff --git a/any.py b/any.py new file mode 100644 index 0000000..d988cc5 --- /dev/null +++ b/any.py @@ -0,0 +1,62 @@ +################################################################################ +# +# Program: any() Built-In Function Examples +# +# Description: Examples of using the built-in any() function in Python to check +# if any item in an iterable object is true. +# +# YouTube Lesson: https://www.youtube.com/watch?v=S_fEefXslrI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The built-in any() function will return True if any item in the iterable +# object it is passed an argument is true. In the below list the last item is +# True so the any() function will return True (which we output with print()). +print(any([False, False, True])) + +# any() function will return False as all items are false +print(any([False, False, False ])) + +# The any() function will work with items that evaluate to True or False, +# such as "abc" which evaluates to True and so the any() function returns True +print(any([False, False, "abc"])) + +# "" evaluates to False so any() returns False +print(any([False, False, ""])) + +# any() returns False for an empty iterable such as the empty list +print(any([])) + +# any() works with iterable objects of different types such as sets, where +# below 0 evaluates to False and 1 evaluates to True so any() returns True +print(any({0, 1})) + +# any() returns False with the set containing only 0 which evaluates to False +print(any({0})) + +# When passed a dictionary any() checks the KEYS of the dictionary and returns +# True if any are True, so with a key of 0 which evaluates to False and a key +# of 1 which evaluates to True any() returns True below. +print(any({0: True, 1: True})) + +# When the dictionary only has a key 0 which evaluates to False it returns False +print(any({0: True})) + +# One good use case of any() comes from using it with list comprehensions. Say +# we have a list of strings and we wish to check if any of the strings start +# with "aga". We could use a loop structure to go through and check if any item +# starts with "aga", or we could use a single line of code using any() and +# a list comprehension instead. +strings = ["apple", "against", "application"] + +# The list comprehension uses the startswith() method with each string in the +# above list to produce a list of True/False values depending on whether each +# string starts with "aga". We then use any() to verify if ANY of the strings +# start with "aga" (which will be the case if any of the list items are True in +# the list produced by the list comprehension). +if any([s.startswith("aga") for s in strings]): + print("a string does begin with 'aga'") +else: + print("no string begins with 'aga'") \ No newline at end of file From 8196ece5da98999c530bd5441c2030579c853d73 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 9 Dec 2023 15:38:34 -0500 Subject: [PATCH 031/101] find longest common prefix in a list of strings --- longest_common_prefix.py | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 longest_common_prefix.py diff --git a/longest_common_prefix.py b/longest_common_prefix.py new file mode 100644 index 0000000..b9d331d --- /dev/null +++ b/longest_common_prefix.py @@ -0,0 +1,72 @@ +################################################################################ +# +# Program: Find The Longest Common Prefix In A List Of Strings +# +# Description: Program to find the longest common prefix in a list of strings +# using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=MbAQiZLWnXU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns string of the longest common prefix in the list of strings +def longest_prefix(strings): + + # Stores the longest common prefix found so far, initially empty/blank + max_prefix = "" + + # Check if strings list is empty (not strings is True if so) and return + # the empty max_prefix string if so + if not strings: + return max_prefix + + # Find the shortest string (min_string) in the strings list using the + # built-in min() function, as the longest common prefix cannot possibly + # be longer than this string by definition (otherwise it would not be + # a common prefix). The keyword argument key=len will have min() use + # the built-in len() length function to determine the "minimum string", + # i.e. the minimum string returned by min() will be the one with the + # shortest length. + min_string = min(strings, key=len) + + # The counter variable i goes from 0 up until but not including the + # length of the min_string with each iteration of the loop. We use + # this counter variable to check if increasingly longer prefixes of + # the min_string are prefixes of all strings, where min_string[:i+1] + # gives us the prefix of the min_string from index 0 up until but + # not including the index i+1. So if the min_string is ape: + # + # - In first loop iteration min_string[:i+1] is "a" + # - In second loop iteration min_string[:i+1] is "ap" + # - In third loop iteration min_string[:i+1] is "ape" + # + # We then use the list comprehension to see if each string in the list + # strings starts with this prefix of the min_string (the startswith + # method will return True if the string does, and False otherwise). The + # built-in all() method will check the list of resulting True/False + # items because if ALL the items are True that means ALL the strings in the + # list have this prefix of the min_string as a prefix. If that is the + # case the all() method will return True, and in that case we update the + # max_prefix string as we have found a new longer common prefix. + # + # We continue to check if longer prefixes of the min_string are common to + # all strings and updating max_prefix if so, until either we reach the end + # of min_string OR we find a prefix of min_string that is NOT a prefix of + # all the other strings. max_prefix will contain the longest common prefix + # and so we return that string. + # + for i in range(0, len(min_string)): + if all([s.startswith(min_string[:i+1]) for s in strings]): + max_prefix = min_string[:i+1] + else: + break + + return max_prefix + +# Test list of strings with "ap" is the longest common prefix +string_list = ["apply", "application", "ape", "apples", "append"] + +# Test the function which should return "ap" +print(longest_prefix(string_list)) \ No newline at end of file From 35337de43b737895e40ef7e28423b276d3616684 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 10 Dec 2023 23:44:28 -0500 Subject: [PATCH 032/101] check if a year is a leap year --- leap_year.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 leap_year.py diff --git a/leap_year.py b/leap_year.py new file mode 100644 index 0000000..772b67d --- /dev/null +++ b/leap_year.py @@ -0,0 +1,60 @@ +################################################################################ +# +# Program: Check If A Year Is A Leap Year +# +# Description: Program to check if a year is a leap year using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Z95edKacyp4 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A year is a leap year if it is: +# +# 1) divisible by 4 but NOT divisible by 100 +# +# OR +# +# 2) divisible by 400 +# +# Where if a year is divisible by a number it means that the year divided +# by the number has a remainder of 0. So 2024 is divisible by 4 because: +# +# 2024 / 4 = 506 remainder 0 +# +# But 2023 is NOT divisible by 4 because: +# +# 2023 / 4 = 505 remainder 3 +# +# The modulus operator % in Python returns the remainder of a division +# operation, so if we have year % 4 == 0 this would be true if the year +# is divisible by 4 and false otherwise. +# +# We use this to create a function to check if a year is a leap or not by +# checking if the year is divisible or not divisible by numbers according +# to the above definition of a leap year. +# + +# Returns True if year is a leap year and False otherwise +def is_leap_year(year): + return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 + +# Prompt the user to enter a year, convert the string entered into an int value +# and store it into year +year = int(input("Enter Year: ")) + +# Call the function to check if the year is a leap year, output appropriate +# text accordingly +if is_leap_year(year): + print(year, "is a leap year") +else: + print(year, "is not a leap year") + +# for loop will run for year = 2020,2021,...,2040, and we output if each year +# in this range is a leap year or not +for year in range(2020,2041): + if is_leap_year(year): + print(year, "is a leap year") + else: + print(year, "is not a leap year") \ No newline at end of file From 79a8e174138b04ea2597ae6f4c9df1efce97c2b4 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:07:56 -0500 Subject: [PATCH 033/101] print even numbers in a list --- print_even_list_numbers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/print_even_list_numbers.py b/print_even_list_numbers.py index 54b5ba8..116a1e6 100644 --- a/print_even_list_numbers.py +++ b/print_even_list_numbers.py @@ -1,6 +1,6 @@ ################################################################################ # -# Program: Print Event Numbers In A List +# Program: Print Even Numbers In A List # # Description: A program to compute the even numbers in a list using Python. # @@ -26,4 +26,4 @@ # for number in listA: if (number % 2 == 0): - print(number) \ No newline at end of file + print(number) From 032768eebd87e736bd93deb4154bdd742d9f4893 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:10:34 -0500 Subject: [PATCH 034/101] print the even numbers in a list --- print_even_list_numbers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print_even_list_numbers.py b/print_even_list_numbers.py index 116a1e6..2217ee6 100644 --- a/print_even_list_numbers.py +++ b/print_even_list_numbers.py @@ -2,7 +2,7 @@ # # Program: Print Even Numbers In A List # -# Description: A program to compute the even numbers in a list using Python. +# Description: A program to print the even numbers in a list using Python. # # YouTube Lesson: https://www.youtube.com/watch?v=jWsx8C_uVCo # From a4dce40c06acc719fda184417798fa6b91695b0c Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:13:02 -0500 Subject: [PATCH 035/101] print the odd numbers in a list --- print_odd_list_numbers.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 print_odd_list_numbers.py diff --git a/print_odd_list_numbers.py b/print_odd_list_numbers.py new file mode 100644 index 0000000..eefa1f0 --- /dev/null +++ b/print_odd_list_numbers.py @@ -0,0 +1,35 @@ +################################################################################ +# +# Program: Print Odd Numbers In A List +# +# Description: A program to print the odd numbers in a list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=B56J6p_v_zY +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list of numbers +numbers = [7,8,9,10,11,12,13,14,15,16,17] + +# If we divide odd numbers such as 7 and 9 by 2 we will get a remainder of 1. +# +# 7 / 2 = 3 remainder 1 +# 8 / 2 = 4 remainder 0 +# 9 / 2 = 4 remainder 1 +# +# The modulus operator in Python % will give us the remainder of a division +# operation, so for example 9 % 2 gives us back 1... +# +# 9 % 2 == 1 + +# Loop through each number in the list, check if it odd, and print it if so. +# +# With each iteration of the loop 'number' will be set to the next number in +# the numbers list. We use number % 2 to get the remainder of dividing the +# number by 2, and if it is equal to 1 we output the number. +# +for number in numbers: + if number % 2 == 1: + print(number) \ No newline at end of file From 0b0b73c34b5ac349cc7e2f0c24971eadd1077e06 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:03:47 -0500 Subject: [PATCH 036/101] print a 2d multiplication table --- multiplication_table_2d.py | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 multiplication_table_2d.py diff --git a/multiplication_table_2d.py b/multiplication_table_2d.py new file mode 100644 index 0000000..4f1163c --- /dev/null +++ b/multiplication_table_2d.py @@ -0,0 +1,75 @@ +################################################################################ +# +# Program: Print A 2D Multiplication Table +# +# Description: A program to print a 2D multiplication table using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=G_3KSbpXjZM +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# This program outputs multiplication tables like the 10x10 table below where +# the numbers of the first row are multiplied by the numbers of the first +# column to give us the product of each, i.e. 6 x 4 = 24. +# +# x 1 2 3 4 5 6 7 8 9 10 +# 1 1 2 3 4 5 6 7 8 9 10 +# 2 2 4 6 8 10 12 14 16 18 20 +# 3 3 6 9 12 15 18 21 24 27 30 +# 4 4 8 12 16 20 24 28 32 36 40 +# 5 5 10 15 20 25 30 35 40 45 50 +# 6 6 12 18 24 30 36 42 48 54 60 +# 7 7 14 21 28 35 42 49 56 63 70 +# 8 8 16 24 32 40 48 56 64 72 80 +# 9 9 18 27 36 45 54 63 72 81 90 +# 10 10 20 30 40 50 60 70 80 90 100 + +# Prompt the user to enter the table dimension, convert the string returned by +# input() into an into and store it into dimension +dimension = int(input("Enter Table Dimension (1...99): ")) + +# If the dimension is in the acceptable range, output the table +if dimension >= 1 and dimension <= 99: + + # All products, row/column headers and 'x' are output into fields of width + # 5 characters so that table columns will have a consistent width. Notably + # 99 x 99 = 9801 and so the max possible dimension of 99 is compatible with + # this field width. + + # Output the 'x' in the first row into a field of width 5 characters, + # right-aligned, using an f-string. > makes it right-aligned. We also + # use the keyword argument end to alter the default behavior of print(), + # this will stop it from outputting a newline \n so we can continue to + # output the column headings on this row. + print(f"{'x':>5}", end="") + + # Output the column headings from 1...dimension, again into fields of width + # 5 characters, right-aligned by default as they are integers. + for n in range(1, dimension + 1): + print(f"{n:5}", end="") + + # Output a newline so next table row begins on the next row of the terminal + # (remember print() outputs a newline by default after the string it is + # passed as an argument) + print("") + + # Loop to create rows from 1...dimension + for n in range(1, dimension + 1): + + # Output the row heading 'n' (1,2,3,... which each loop iteration) + print(f"{n:5}", end="") + + # On this same row, output the products of multiplying this row's + # number 'n' with the column numbers i=1,2,...,n + for i in range(1, dimension + 1): + print(f"{i*n:5}", end="") + + # Output a newline at the end of each table row so the next row outputs + # on the next line of the terminal + print("") + +# Otherwise output an error message if dimension not in range +else: + print("Dimension must be in the range 1...99") \ No newline at end of file From 1b2dc3b61e6c39b85508ed1d6896409764360bd0 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 15 Dec 2023 23:41:05 -0500 Subject: [PATCH 037/101] print a 1d multiplication table --- multiplication_table_1d.py | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 multiplication_table_1d.py diff --git a/multiplication_table_1d.py b/multiplication_table_1d.py new file mode 100644 index 0000000..6fad451 --- /dev/null +++ b/multiplication_table_1d.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Print A 1D Multiplication Table +# +# Description: A program to print a 1D multiplication table using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ZO5tsBSbdn4 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# This program outputs "1D" multiplication tables like the one below, where a +# number (in this case 5) is multiplied by all integers from 1 to some limit +# (in this case 10). +# +# 5 x 1 = 5 +# 5 x 2 = 10 +# 5 x 3 = 15 +# 5 x 4 = 20 +# 5 x 5 = 25 +# 5 x 6 = 30 +# 5 x 7 = 35 +# 5 x 8 = 40 +# 5 x 9 = 45 +# 5 x 10 = 50 + +# Prompt the user to enter the number and limit. We convert the string that +# input() returns to an int and store the int values into number and limit. +number = int(input("Number: ")) +limit = int(input("Limit: ")) + +# We can't really create a multiplication table if the limit is less than or +# equal to 0, so in this case we output an error message +if limit <= 0: + print("Limit must be greater than 0") +# Otherwise we output the multiplication table +else: + # This for loop will execute for i=1,2,...limit with each loop iteration, + # and output number x i = number*i with each iteration to build the table + for i in range(1, limit+1): + print(number, "x", i, "=", number * i) From c9b753db35e9e946d2043e75bfb97f257b6357f4 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:39:31 -0500 Subject: [PATCH 038/101] mask a credit card --- credit_card_mask.py | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 credit_card_mask.py diff --git a/credit_card_mask.py b/credit_card_mask.py new file mode 100644 index 0000000..536246c --- /dev/null +++ b/credit_card_mask.py @@ -0,0 +1,49 @@ +################################################################################ +# +# Program: Mask A Credit Card +# +# Description: Program to mask credit card numbers using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=dMO35dBZ8oA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import re + +# returns a masked credit card string for the string credit_card, leaving +# unmasked_digits number of digits unmasked and hiding digits using the +# mask_character. +def mask_credit_card(credit_card, unmasked_digits=4, mask_character='*'): + + # Find the total number of digits in the credit_card string by calling + # the isdigit() method for each character in the string as part of a + # list comprehension... producing a list of True/False values, we then + # count the number of True values (digits) using the list count() method. + total_digits = [c.isdigit() for c in credit_card].count(True) + + # It doesn't make any sense to leave more digits unmasked than there are + # digits total in the credit card, so if this occurs we should output an + # error message, raise an exception, or return None, i.e. something to + # acknowledge an error has taken place. + if unmasked_digits > total_digits: + return None + + # Determine the total number of digits needed to be replaced + total_replace_digits = total_digits - unmasked_digits + + # Use the sub() function of the regular expression module to replace + # total_replace digits number of digits in the string credit_card with + # the mask_character, where \\d is a pattern that will match for digits. + return re.sub("\\d", mask_character, credit_card, total_replace_digits) + +# Test the function by masking all but the last 6 digits of credit_card1, the +# default mask_character of '*' will be used since we don't supply the argument. +credit_card1 = "3776222750878661" +print(mask_credit_card(credit_card1, 6)) + +# Again test the function by masking all but the last 5 digits of credit_card2, +# this time using the '#' character to mask digits. +credit_card2 = "5545 4234 6381 71925" +print(mask_credit_card(credit_card2, 5, "#")) \ No newline at end of file From e21fcd30d66ce3b38163f57a16bccaf256b421a8 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 14 Jan 2024 23:22:49 -0500 Subject: [PATCH 039/101] count the digits in a string --- count_digits_in_string.py | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 count_digits_in_string.py diff --git a/count_digits_in_string.py b/count_digits_in_string.py new file mode 100644 index 0000000..398429c --- /dev/null +++ b/count_digits_in_string.py @@ -0,0 +1,44 @@ +################################################################################ +# +# Program: Count The Digits In A String +# +# Description: Count the total number of digits in a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=w5y6FFJFsqs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A test string containing 3 digits: 2, 4 and 7 +text = "Open 24 hours a day, 7 days a week" + +# A more traditional approach to counting the number of digits in the string +# would be to use a loop. We set a count variable initially to zero, then +# use a for loop to examine each character in the string. Each time the for +# loop body executes 'c' will be set to the next character in the string, +# starting with the first character in the string and ending with the last +# character. Technically 'c' is a string made up of one character, so we +# use the string method isdigit() which will return True if 'c' is a digit +# and False otherwise. ONLY if the method returns True because the character +# is a digit do we increment count. So by the end of the loop's execution +# count will store the total count of all digits in the string! + +count = 0 +for c in text: + if c.isdigit(): + count += 1 + +print("Total Digits:", count) + + +# In this approach we use a list comprehension, where 'c' will be set to each +# character (i.e. string of one character) in the string, and we call the +# isdigit() method for each character. This will result in a list made up +# of the return values of these function calls, i.e. False for non-digit +# characters and True for digits. We then use the list method count to +# count the number of True items in the list, because this is the number +# of digits in the string. +count = [c.isdigit() for c in text].count(True) + +print("Total Digits:", count) \ No newline at end of file From 2455f16bdf99cd9b386399076f6d9f7899325136 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:29:44 -0500 Subject: [PATCH 040/101] count the letters in a string --- count_letters_in_string.py | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 count_letters_in_string.py diff --git a/count_letters_in_string.py b/count_letters_in_string.py new file mode 100644 index 0000000..18bd04c --- /dev/null +++ b/count_letters_in_string.py @@ -0,0 +1,44 @@ +################################################################################ +# +# Program: Count The Letters In A String +# +# Description: Count the total number of letters in a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ogm3IZG8Bf8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A test string containing 13 letters +text = "Open 24 hours a day" + +# A more traditional approach to counting the number of letters in the string +# would be to use a loop. We set a count variable initially to zero, then +# use a for loop to examine each character in the string. Each time the for +# loop body executes 'c' will be set to the next character in the string, +# starting with the first character in the string and ending with the last +# character. Technically 'c' is a string made up of one character, so we +# use the string method isalpha() which will return True if 'c' is a letter +# and False otherwise. ONLY if the method returns True because the character +# is a letter do we increment count. So by the end of the loop's execution +# count will store the total count of all letters in the string! + +count = 0 +for c in text: + if c.isalpha(): + count += 1 + +print("Total Letters:", count) + + +# In this approach we use a list comprehension, where 'c' will be set to each +# character (i.e. string of one character) in the string, and we call the +# isalpha() method for each character. This will result in a list made up +# of the return values of these function calls, i.e. False for non-letter +# characters and True for letters. We then use the list method count to +# count the number of True items in the list, because this is the number +# of letters in the string. +count = [c.isalpha() for c in text].count(True) + +print("Total Letters:", count) \ No newline at end of file From b488de5b4eba21227c700e9d335d75ff8953af93 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 16 Jan 2024 00:28:58 -0500 Subject: [PATCH 041/101] count the digits and letters in a string --- count_digits_and_letters_in_string.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 count_digits_and_letters_in_string.py diff --git a/count_digits_and_letters_in_string.py b/count_digits_and_letters_in_string.py new file mode 100644 index 0000000..04cb0c6 --- /dev/null +++ b/count_digits_and_letters_in_string.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Count The Digits And Letters In A String +# +# Description: Count the total number of digits and letters in a string using +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=B8Cd2AH1lIE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the total number of letters and digits in the string 'text' +def count_letters_and_digits(text): + + # Variables will store the running counts of letters and digits found + total_letters = 0 + total_digits = 0 + + # Loop body will execute for each character in the string text, with c set + # to a string made up of that one character. We use the isalpha() method + # and isdigit() string methods to check if the character is a letter or + # digit respectively, and increment the correct running counts if so. + for c in text: + if c.isalpha(): + total_letters += 1 + elif c.isdigit(): + total_digits += 1 + + # We use the , to return two values from the function (both counts) + return total_letters, total_digits + +# Test string with 2 digits and 13 letters +text1 = "Open 24 hours a day" + +# Test the function, store the values returned into ltotal and dtotal +ltotal, dtotal = count_letters_and_digits(text1) + +# Output the totals +print("Total Digits:", dtotal) +print("Total Letters:", ltotal) \ No newline at end of file From 116a6e804390b26eb3f6f817e1e78ae4dcb2e73e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 16 Jan 2024 21:57:12 -0500 Subject: [PATCH 042/101] walrus operator examples --- walrus_operator.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 walrus_operator.py diff --git a/walrus_operator.py b/walrus_operator.py new file mode 100644 index 0000000..d745236 --- /dev/null +++ b/walrus_operator.py @@ -0,0 +1,82 @@ +################################################################################ +# +# Program: Walrus Operator Examples +# +# Description: Basic examples of using the walrus operator in Python, also +# officially known as the assignment expression operator. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Y5rDTHve8M4 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The walrus operator := will assign a value to the variable (in this case 1) +# but also return the value assigned to the variable (1) to the expression in +# which it is used, so this will become y = 1 + 1 and y will be set to 2 and +# x to 1 by the below statement. +y = 1 + (x := 1) + +# x will be 1 and y will be 2 +print("y:", y) +print("x:", x) + +# Notably we can't have this... +# +# y = 1 + x := 1 +# +# Python syntax will not allow for it. The walrus operator has lower precedence +# than everything but the comma, so the above expression would be like trying +# to add "x := 1" to 1, which doesn't make sense. + +# By design the walrus operator can't be used in the exact same places and ways +# as the assignment statement, so if we want to assign a value to a variable +# like the below we can't do it exactly like an assignment statement with +# z := 5, we would need brackets to make it work... +# +(z := 5) + +# The above will work and z will be set to 5 +print("z:", z) + + +# If we want to prompt the user to enter numbers and append those numbers +# to a list until the user enters -1, without using the walrus operator +# we might do it like this... + +# Create an empty list +data = [] + +# Continue the loop until we use break to stop the loop +while True: + + # Prompt the user to enter the number and store it into number + number = int(input("Enter number (-1 to quit): ")) + + # Stop the loop with break if the number -1 was entered + if number == -1: + break + + # Append the number to the list + data.append(number) + +# Output the list +print(data) + + +# Using the Walrus operator we can shorten the above code by prompting the +# user to enter the number right inside the while loop condition and +# assigning the result, using the walrus operator, to number. Then because +# the walrus operator will return the value assigned to number, still as +# part of the while loop condition, we can check to see if the user did +# not enter -1, in which case we want to continue the loop. The loop body +# now simply appends the number to the list. This saves us 3 lines of +# code and arguably makes the code simpler/easier to follow (though of +# course this is subjective). + +data = [] + +while number := int(input("Enter number (-1 to quit): ")) != -1: + data.append(number) + +print(data) \ No newline at end of file From e20022b483a8aa23b15291a000089b3b9a448e97 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 24 Jan 2024 00:25:45 -0500 Subject: [PATCH 043/101] dictionary examples --- dictionaries.py | 232 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 dictionaries.py diff --git a/dictionaries.py b/dictionaries.py new file mode 100644 index 0000000..c6c9241 --- /dev/null +++ b/dictionaries.py @@ -0,0 +1,232 @@ +################################################################################ +# +# Program: Dictionaries Examples +# +# Description: Examples of using the dictionaries built-in data structure in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=cgTUCCEE2Xc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The deepcopy() function in this module is used to create a deep copy of +# a dictionary +import copy + +# Dictionaries are made up of key-value pair items +student = { + "name" : "Grace Hopper", + "age" : 22, + "gpa" : 3.7 +} + +# Output the dictionary +print(student) + +# The len() function returns the number of items in the dictionary (3 in this +# case) +print(len(student)) + +# The type of the dictionary will be 'dict' +print( type(student) ) + +# We can use immutable types as keys as well as tuples made up of numbers, +# strings and tuples. We can use any type of object as a key. So we can +# use the immutable type boolean values False and True as keys, and +# mutable list objects as values. +trybools = {False: [1,2,3], True: [4,5,6]} +print(trybools) + +# We can use dict() to create dictionary, the keyword argument identifiers +# name and gpa will become string keys in the dictionary. +ada = dict( name = "Ada", gpa = 3.7) +print(ada) + +# We can create empty dictionaries with no items... +empty_dictionary = {} +print(empty_dictionary) + +# Create another simple dictionary +course = { + "name" : "Python 101", + "average" : 85.5, +} + +# We can access values by key using this syntax +print( course["name"] ) + +# Trying to access a key that does not exist will produce an error +# print( course["teacher"] ) + +# We can also use .get() to access a value by passing the key as an argument +print( course.get("average") ) + +# We can update the value for a key like this... +course["average"] = 90.2 +print(course["average"]) + +# We can insert a new key-value pair like this, i.e. a new item... +course["room number"] = 205 +print(course) + +# We can update the values of a dictionary and insert new items using the +# update() method... +course.update({"name" : "Python 102", + "average" : 75.4, + "teacher" : "Barbara Liskov"}) +print(course) + +# We can't create a copy of a dictionary by just assigning it to a variable, +# instead the variable will just reference the same dictionary object in +# memory. So if we try to update a value in the dictionary using the variable +# we assigned to, it will actually update the same dictionary that the +# original variable references... i.e. the dictionary that course references +# will be updated with the key value 'teacher' set to 'Fred'. +variable = course +variable["teacher"] = "Fred" +print(course) + +# We can use the copy() method to create a (shallow) copy of the dictionary, +# and now course_copy will reference a NEW dictionary object. So when we +# update the value at the 'teacher' key, ONLY this copied dictionary object +# will have its value changed and not the original dictionary object. +course_copy = course.copy() +course_copy["teacher"] = "Joe" +print(course) +print(course_copy) + +# We can loop through the keys of a dictionary with a for loop, and use them +# to access the values in the dictionary (course[key] below). Each time the +# loop body executes 'key' will be set to the next key in the dictionary. +for key in course: + print(key, course[key]) + +# Create a dictionary and add an additional item to it as well +school = { + "name" : "Harvard", + "city" : "Cambridge", + "country" : "USA" +} +school["founded"] = 1636 +print(school) + +# The popitem() method will remove the last item added to the dictionary, in +# this case the item with the key "founded". +school.popitem() +print(school) + +# We can use pop() to remove an item with the associated key, in this case the +# item with the key "city". +school.pop("city") +print(school) + +# A del statement an also be use to remove an item, in this case the item with +# the key "country". +del school["country"] +print(school) + +# The clear() method will remove all items from the dictionary making it empty. +school.clear() +print(school) + +# A del statement can be used to delete the dictionary object itself, so in +# the below case we can't even use "school" after deleting the dictionary with +# the del statement. +del school +# print(school) + +# Create a simple dictionary +x = {"A" : 1, "B" : 2, "C" : 3} + +# The keys method will return a view object of the keys in the dictionary +x_keys = x.keys() +print(x_keys) + +# The values method will return a view object of the values in the dictionary +x_values = x.values() +print(x_values) + +# The items method will return a view object of the key-value pairs in the +# dictionary as tuples +x_items = x.items() +print(x_items) + +# If we modify the items or insert new items into the dictionary, the view +# objects will ALSO be update. Here we insert a new item with the key "D" +# and the value 4. +x["D"] = 4 + +# If we output the same view objects we'll notice the new item is reflected +# in the output... +print( x_keys ) +print( x_values ) +print( x_items ) + +# We can loop through the items in the view objects, for example here we loop +# through the values of the dictionary. +for value in x.values(): + print(value) + +# And here we loop through they key-value pairs of the dictionary which are +# tuples of the view object returned by the items() method. +for key, value in x.items(): + print(key, value) + +# We can use 'in' to check if a key is in a dictionary +if "E" in x: + print("E is in x") +else: + print("E is not in x") + +# A dictionary can have a dictionary as a value, we would call this a nested +# dictionary. Other types of objects can be nested too, e.g. lists. +math_class = { + "course" : "Calculus", + "teacher" : { + "name" : "John Nash" + } +} + +# We use this syntax to access the values of the nested dictionary. +print( math_class["teacher"]["name"] ) + +# The copy() method creates a shallow copy of the dictionary, what this means +# is that the nested dictionary will not be copied. Instead, the new copied +# dictionary created by copy() will reference the SAME nested dictionary as +# in the original dictionary object. So if below we change the teacher name +# to "Isaac Newton", this would change the nested dictionary in the original +# dictionary object math_class because it's the same nested dictionary +# that the math_copy dictionary object references. +# +# math_copy = math_class.copy() + +# If we use the deepcopy() function of the copy module then a deep copy of the +# dictionary will be made, where copies of the nested dictionaries (and other +# objects) will be made too. So then if later on we modify the teacher name +# to "Isaac Newton" in the new copied dictionary object, this will not alter +# the teacher name in the original object, because they each have their own +# separate nested dictionaries. +math_copy = copy.deepcopy(math_class) + +# Modify the key "name" of the nested dictionary +math_copy["teacher"]["name"] = "Isaac Newton" + +# Output the original dictionary... because a deep copy was made the nested +# dictionary it contains will not be modified by the above statement. +print(math_class) + +# The items in a dictionary are ordered by insertion as of Python 3.7, so these +# two dictionaries have the same items but in different orders. +m = {"x" : 1, "y" : 2} +n = {"y" : 2, "x" : 1} + +# We can see the different orders if we output the dictionaries +print(m) +print(n) + +# Notably a check for equality with == will show the dictionaries ARE considered +# equal despite the order of the items being different. +if m == n: + print("m == n") \ No newline at end of file From 2326b5e55ba60dc8c28afbce5eeccfc7fdb4513c Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:07:52 -0500 Subject: [PATCH 044/101] create a list of numbers from user input --- list_numbers_from_user_input.py | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 list_numbers_from_user_input.py diff --git a/list_numbers_from_user_input.py b/list_numbers_from_user_input.py new file mode 100644 index 0000000..5054a0b --- /dev/null +++ b/list_numbers_from_user_input.py @@ -0,0 +1,85 @@ +################################################################################ +# +# Program: Create A List Of Numbers From User Input +# +# Description: Approaches to create a list of numbers accepted from user input +# using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=KQavWedyDHE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# There are many approaches to creating a list of numbers from user input, here +# are 3 approaches... + + +# Approach #1 - Prompt the user for the total amount of numbers, then use a loop +# to input this many numbers. + +# Begin with an empty list +numbers = [] + +# Prompt the user for the total amount of numbers to be entered (we use int() to +# convert the string returned by input() to an int value). +total = int(input("Total Numbers: ")) + +# Output an error if the total is negative, we can't have a list with a negative +# amount of numbers +if total < 0: + print("Cannot enter negative total numbers") +else: + # Otherwise this will run 'total' amount of times with i going from 1 to + # total by 1 with each loop iteration. We prompt the user to enter each + # number with "Number 1: ", "Number 2: " and so on (converting i to a string + # with str() and concatenating the strings with +). We append the converted + # int value (done again with int()) to the numbers list. + for i in range(1, total+1): + number = int(input("Number " + str(i) + ": ")) + numbers.append(number) + +# Output the numbers list +print(numbers) + + +# Approach #2 - Prompt the user to enter numbers and append them to a list until +# they enter a special "sentinel" value that indicates they wish to stop +# inputting numbers. + +# Begin with an empty list +numbers = [] + +# Each time the loop condition is evaluated the user will be prompted to enter +# a number using input(), and number will be assigned the string they enter +# using the walrus operator (:=). The walrus operator will ALSO result in +# the expression as a whole (number := input ....) evaluating to whatever was +# assigned to number, which we then check if it does not equal the string "q". +# So as long as the user enters in integers like 4,5,etc they will not equal +# "q". But once the user enters in the special sentinel value "q" the +# loop will stop because "q" == "q" and the condition is false. Each time +# the user enters a number we append it to the numbers list. +# +while (number := input("Number (q to quit): ")) != "q": + numbers.append(int(number)) + +# Output the resulting numbers list +print(numbers) + + +# Approach #3 - Ask the user to enter all the numbers at once separated by +# spaces and use a list comprehension to create a list of the entered numbers. + +# Calling input() prompts the user to enter in a list of numbers separated by +# spaces, which will result in a string like this if the user enters in 9, 8 +# and 7: "9 8 7". The split() method will then split the string into a list +# of string separating them according to the spaces in the original string, +# so for the above string we would then have ["9", "8", "7"]. Finally the +# list comprehension [int(s) for .... ] will then take each of these strings +# and return the list that results in applying the int() function to each one +# of them (converting them all to int values). +# +l = [int(s) for s in input("List (1 2 ...): ").split()] + +# Output the resulting list +print(l) \ No newline at end of file From 71e19227d7c675ff403b67e5df82827f97ea1648 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 6 Feb 2024 20:38:26 -0500 Subject: [PATCH 045/101] random password generator --- random_password_generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/random_password_generator.py b/random_password_generator.py index 1f7394e..9d57ea5 100644 --- a/random_password_generator.py +++ b/random_password_generator.py @@ -43,7 +43,7 @@ # which is a character chosen at random from chars (technically, each element # is a string of one character). The join string method will then join these # string together, separated by '' nothing, to give us our password. -password = ''.join([random.choice(chars) for i i range(length)]) +password = ''.join([random.choice(chars) for i in range(length)]) # Output the randomly generated password -print("Your random password is:", password) \ No newline at end of file +print("Your random password is:", password) From 4a8e39955dd050a651fe09f6681461c918531a71 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:12:06 -0500 Subject: [PATCH 046/101] generate a random string --- generate_random_string.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 generate_random_string.py diff --git a/generate_random_string.py b/generate_random_string.py new file mode 100644 index 0000000..77beead --- /dev/null +++ b/generate_random_string.py @@ -0,0 +1,28 @@ +################################################################################ +# +# Program: Generate A Random String +# +# Description: Program to generate a random string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=A9Px0M1ucQI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import random +import string + +def create_random_string(length, chars): + return ''.join([random.choice(chars) for i in range(length)]) + +# possible_characters = string.ascii_letters +# possible_characters += string.digits +# possible_characters += string.punctuation + +string_length = int(input("Random String Length: ")) +possible_characters = input("Possible Characters: ") + +print( create_random_string(string_length, possible_characters) ) + +# print( string.ascii_letters ) From d4c24627d3929e92e5119ddc2bd857badf62e7da Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:50:21 -0500 Subject: [PATCH 047/101] generate a random string --- generate_random_string.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/generate_random_string.py b/generate_random_string.py index 77beead..27bb8bd 100644 --- a/generate_random_string.py +++ b/generate_random_string.py @@ -13,16 +13,47 @@ import random import string +# Returns a random string of length 'length' made up of the charaters in the +# string 'chars'. The list comprehension will produce a a list of length +# 'length' with each item a string of one character chosen at random from +# the chars string (random.choice(chars) will return a string of one character +# randomly chose from chars). We then use the string method .join() to join +# these list items together into one string separated by the emptry string '' +# (i.e. a join with no separater characters). +# def create_random_string(length, chars): return ''.join([random.choice(chars) for i in range(length)]) + +# Alternatively we could implement the function like this, beginning with an +# empty string and then using a loop that will execute length times to +# concatenate one random character from chars each time to the string, and +# then returning the completed string. +# +# def create_random_string(length, chars): +# random_string = "" +# for i in range(length): +# random_string += random.choice(chars) +# return random_string + + +# Prompt the user for the length of the random string and a string of the +# possible characters. We use int() to convert the entered length into an +# int value as the input() function prompts the user with the text of the +# provided string and returns the string they enter. +# +string_length = int(input("Random String Length: ")) +possible_characters = input("Possible Characters: ") + + +# Alternatively we could use the constants defined in the string module to +# build a string of possible characters, in this case all the ascii_letters +# a-z and A-Z, digits 0-9, and punctuation marks. +# # possible_characters = string.ascii_letters # possible_characters += string.digits # possible_characters += string.punctuation -string_length = int(input("Random String Length: ")) -possible_characters = input("Possible Characters: ") +# Test function with provided string length and possible characters string print( create_random_string(string_length, possible_characters) ) - -# print( string.ascii_letters ) From e095412097b89e752beb0f5737e737133830c9e2 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:25:19 -0500 Subject: [PATCH 048/101] generate a random boolean --- generate_random_boolean.py | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 generate_random_boolean.py diff --git a/generate_random_boolean.py b/generate_random_boolean.py new file mode 100644 index 0000000..31634e1 --- /dev/null +++ b/generate_random_boolean.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Generate A Random Boolean +# +# Description: Techniques to generate a random boolean using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=p4SpxIOj0jE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# All techniques will use functions in the random module +import random + +# Technically we could improve performance with the below import of getrandbits +# (and/or choice if we use the 1st technique) instead of "import random" because +# one less name lookup would be required. +# +# from random import getrandbits + +# choice() will return True or False randomly, this technique is very readable +value = random.choice([True,False]) + +# While less readable we can improve performance using getrandbits(1) which will +# return a non-negative integer with 1 bit randomly set (so the integer will be +# either 0 or 1). When we use bool() to convert the returned 1 or 0 to a bool +# we will get True (for 1) or False (for 0). +value = bool(random.getrandbits(1)) + +# We can improve performance more by using the not operator, as not 1 will +# result in False and not 0 will result in True. +value = not random.getrandbits(1) + +# If we used the 2nd form of import above commented out, this would also improve +# performance, and we would then call the function like this... +# +# value = getrandbits(1) + +# Output the generated boolean (note that we should comment/uncomment the above +# statements to test out the different methods). +print(value) \ No newline at end of file From 6401d2038d0a10d96411c7d0623331e35d69491f Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 20 Feb 2024 00:07:22 -0500 Subject: [PATCH 049/101] find the first non-repeating item in a list --- first_non_repeating_list_item.py | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 first_non_repeating_list_item.py diff --git a/first_non_repeating_list_item.py b/first_non_repeating_list_item.py new file mode 100644 index 0000000..fb0cf79 --- /dev/null +++ b/first_non_repeating_list_item.py @@ -0,0 +1,51 @@ +################################################################################ +# +# Program: Find The First Non-Repeating Item In A List +# +# Description: Find the first non-repeating item in a list using Python (i.e. +# the first unique item in a list). +# +# YouTube Lesson: https://www.youtube.com/watch?v=S3ZjcPs37AU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the first non-repeating (unique) item in the list lst supplied as +# an argument, or None if all items are repeating +def first_non_repeating(lst): + + # Dictionary to keep track of number of occurrences of each value in list + occurrences = {} + + # Loop through each item in the list and count the occurrences of each + # value that occurs. If we encounter a value for the first time, we set + # a key for that value in the dictionary to 1 as we have encountered the + # value 1 time. If we have already encountered the value before, it will + # be in the occurrences dictionary, and we can increment the existing + # count by 1. + for item in lst: + if item in occurrences: + occurrences[item] += 1 + else: + occurrences[item] = 1 + + # Loop through the items in list again, and return the first item where + # the value occurred only once in the list when counted above. + for item in lst: + if occurrences[item] == 1: + return item + + # If the loop above never returns all the items of the list (if it is not + # empty) must be repeating and we can return None + return None + +# Create a test list and call function, we'll find 9 is the first non-repeating +# item in the list +numbers = [4,5,1,5,9,3,4,5,1,8,6,3,2,5,7,1,2,5] +print( first_non_repeating(numbers) ) + +# Create a test list and call the function, we'll find this list has no +# non-repeating items and we get back None +other_numbers = [1,2,3,4,1,2,3,4] +print( first_non_repeating(other_numbers) ) \ No newline at end of file From df90446016cce55e24ff8b548acd2fd410d61a7a Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:18:51 -0500 Subject: [PATCH 050/101] find the first repeating item in a list --- first_repeating_list_item.py | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 first_repeating_list_item.py diff --git a/first_repeating_list_item.py b/first_repeating_list_item.py new file mode 100644 index 0000000..b6ff2f6 --- /dev/null +++ b/first_repeating_list_item.py @@ -0,0 +1,50 @@ +################################################################################ +# +# Program: Find The First Repeating Item In A List +# +# Description: Find the first repeating item in a list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=fHLDc8t1x4c +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the first repeating item in the list lst supplied as an argument, or +# None if no items are repeating +def first_repeating(lst): + + # Dictionary to keep track of number of occurrences of each value in list + occurrences = {} + + # Loop through each item in the list and count the occurrences of each + # value that occurs. If we encounter a value for the first time, we set + # a key for that value in the dictionary to 1 as we have encountered the + # value 1 time. If we have already encountered the value before, it will + # be in the occurrences dictionary, and we can increment the existing + # count by 1. + for item in lst: + if item in occurrences: + occurrences[item] += 1 + else: + occurrences[item] = 1 + + # Loop through the items in list again, and return the first item where + # the value occurred more than once in the list when counted above. + for item in lst: + if occurrences[item] > 1: + return item + + # If the loop above never returns all the items of the list (if it is not + # empty) must be unique and we can return None + return None + +# Create a test list and call the function and we'll find 4 is the first +# repeating item in the list +numbers = [1,2,3,4,5,6,7,8,9,4,5,6,7,8,4,5,6] +print( first_repeating(numbers) ) + +# Create a test list and call the function, we'll find this list has no +# repeating items and we get back None +other_numbers = [1,2,3,4,5,6,7,8] +print( first_repeating(other_numbers) ) \ No newline at end of file From ff0353119b35e479907217d81770f92c1060ac15 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:11:50 -0500 Subject: [PATCH 051/101] count the occurrences of each item in a list --- count_each_list_item_occurrences.py | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 count_each_list_item_occurrences.py diff --git a/count_each_list_item_occurrences.py b/count_each_list_item_occurrences.py new file mode 100644 index 0000000..6a1eded --- /dev/null +++ b/count_each_list_item_occurrences.py @@ -0,0 +1,67 @@ +################################################################################ +# +# Program: Count The Occurrences Of Each Item In A List +# +# Description: Count the occurrences of each item (value) in a list with Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=GiF1tm37UEs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# We can use the built-in Counter class of the collections module to solve this +# problem (or we could create our own function like find_counts()) +from collections import Counter + +# Returns a dictionary containing the number of occurrences of each value/item +# in the lst list, where the dictionary keys are the values/items that occur in +# the list and they are set to the number of occurrences of those values/items. +def find_counts(lst): + + # Begin with an empty dictionary as we have counted no occurrences of any + # values yet + counts = {} + + # Loop through each item in the list, if it's the first time we've + # encountered the value it won't be in the dictionary so create a new + # key for the value (item) and set it to 1, otherwise if the value + # already is in the dictionary we increment the running count of the + # number of occurrences of the value. + for item in lst: + if item in counts: + counts[item] += 1 + else: + counts[item] = 1 + + # return the dictionary + return counts + + +# A test list of numbers +numbers = [1,4,5,8,3,5,6,8,9,1,3,5,6,8,5,7,8] + +# The Counter() object produced when passed numbers will contain a count of the +# number of occurrences of each value in the list. +counts = Counter(numbers) + +# We can see this if we output counts +print(counts) + +# We can access the Counter() object much like a dictionary, e.g. the below +# will give us the number of occurrences of the value 7 in our numbers list +print(counts[7]) + +# We can loop through the keys of the Counter object like we would a dictionary +# and output the count of the number of occurrences of each value in the list +for item in counts: + print(item, "-", counts[item]) + +# Test out the find_counts() function +counts_again = find_counts(numbers) + +# If like above we loop through the keys of the dictionary we can output the +# count of the number of occurrences of each value in the list and we'll find it +# matches what the Counter() object contains! +for item in counts_again: + print(item, "-", counts[item]) \ No newline at end of file From 57a3029406227a0eea790c9c6ae6e801e00247e3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 25 Feb 2024 21:15:54 -0500 Subject: [PATCH 052/101] count the occurrences of each item in a list --- count_each_list_item_occurrences.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/count_each_list_item_occurrences.py b/count_each_list_item_occurrences.py index 6a1eded..711c503 100644 --- a/count_each_list_item_occurrences.py +++ b/count_each_list_item_occurrences.py @@ -4,7 +4,7 @@ # # Description: Count the occurrences of each item (value) in a list with Python. # -# YouTube Lesson: https://www.youtube.com/watch?v=GiF1tm37UEs +# YouTube Lesson: https://www.youtube.com/watch?v=TOkSElso_Fk # # Author: Kevin Browne @ https://portfoliocourses.com # @@ -64,4 +64,4 @@ def find_counts(lst): # count of the number of occurrences of each value in the list and we'll find it # matches what the Counter() object contains! for item in counts_again: - print(item, "-", counts[item]) \ No newline at end of file + print(item, "-", counts[item]) From fc2d31e40762e1c189a749660ab685f1805707ea Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 1 Mar 2024 06:54:37 -0500 Subject: [PATCH 053/101] sum the numbers in a list using recursion --- sum_list_numbers_recursion.py | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 sum_list_numbers_recursion.py diff --git a/sum_list_numbers_recursion.py b/sum_list_numbers_recursion.py new file mode 100644 index 0000000..665fd99 --- /dev/null +++ b/sum_list_numbers_recursion.py @@ -0,0 +1,56 @@ +################################################################################ +# +# Program: Sum The Numbers In A List Using Recursion +# +# Description: Sum the numbers in a list using recursion with Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=KKxRNFFYaf0 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the sum of the numbers in the list lst using recursion +# +# If the list is empty (not lst is True if the list lst is empty) we return 0 +# as the sum of the numbers in an empty list is reasonably said to be 0. This +# is also the "base case" where recursion will stop and function will stop +# calling itself (also know as the "base step"). +# +# Otherwise the function calls itself, returning the sum of the first item in +# the list as given by lst[0] with the sum of the remaining items in the list +# as given by calling sum_list with lst[1:] which uses the slicing operator +# to obtain the remaining items in the list after the first item. This is +# called the "recursive case" or "recursive step", as the function calls itself, +# solving part of the problem and calling itself with a smaller version of the +# same problem as is often the case with recursive solutions to problems. +# +# Eventually the function will stop calling itself when the remaining portion +# of the list is empty. +# +def sum_list(lst): + if not lst: + return 0 + else: + return lst[0] + sum_list(lst[1:]) + + +# Test the function with a list of numbers. Recursion will look like this in +# this case... +# +# sum_list([4,1,3]) +# | +# 4 + sum_list([1,3]) +# | +# 1 + sum_list([3]) +# | +# 3 + sum_list([]) +# | +# 0 +# +numbers = [4,1,3] +print( sum_list(numbers) ) + +# Test the function with the empty list +numbers = [] +print( sum_list(numbers) ) \ No newline at end of file From db33cc5765dda58d3581d1a608a44e63adc03f16 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 3 Mar 2024 00:42:11 -0500 Subject: [PATCH 054/101] count occurrences of value in list using recursion --- count_list_value_occurrences_recursion.py | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 count_list_value_occurrences_recursion.py diff --git a/count_list_value_occurrences_recursion.py b/count_list_value_occurrences_recursion.py new file mode 100644 index 0000000..f82aa98 --- /dev/null +++ b/count_list_value_occurrences_recursion.py @@ -0,0 +1,46 @@ +################################################################################ +# +# Program: Count The Occurrences Of A Value In A List Using Recursion +# +# Description: Count the occurrences of a value in a list using recursion in +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=LmSKX5vTWAU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the occurrences of the parameter value in the list parameter lst. +# +# If the list is empty (not lst is True if the list lst is empty) we return 0 +# as the value cannot occur any times in a list that is empty. This +# is also the "base case" where recursion will stop and function will stop +# calling itself (also know as the "base step"). +# +# Otherwise if the first item in the list matches the value we are looking for +# we return 1 plus the number of occurrences of the value in the remaining +# portion of the list. We use the count function to obtain the number of +# occurrences in the remaining portion of the list, passing it lst[1:] which +# uses the slicing operator to give us the list containing all the items +# after the first item. If we first item in the list does not match the value +# we are looking for then we just return the number of occurrences of the value +# in the remaining portion of the list. +# +# Eventually the function will stop calling itself when the remaining portion +# of the list is empty. +# + +def count(lst, value): + if not lst: + return 0 + elif lst[0] == value: + return 1 + count(lst[1:], value) + else: + return count(lst[1:], value) + + +# Test the function with a list of numbers, count the occurrences of 4 (2). +# +numbers = [4,1,4,2] +print( count(numbers, 4) ) \ No newline at end of file From 35d8fb3aef3045d017bd7272b6f4bd688d78849e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:41:10 -0500 Subject: [PATCH 055/101] sum the digits in a string --- sum_string_digits.py | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 sum_string_digits.py diff --git a/sum_string_digits.py b/sum_string_digits.py new file mode 100644 index 0000000..b048679 --- /dev/null +++ b/sum_string_digits.py @@ -0,0 +1,57 @@ +################################################################################ +# +# Program: Sum The Digits In A String +# +# Description: Functions to sum the digits in a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=AoHjSi-0-BA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the sum of the digits in the string text +def sum_digits(text): + + # Used to sum the digits, initialized to 0 as no digits have been looked at + total = 0 + + # Loops through each character in the string text, where with each loop + # iteration 'character' will be set to a string made up of only the next + # character in the string. We use the string method isdigit() to check if + # that character is a digit as the method will return True if it is and + # False otherwise. Only if that character is a digit do we use int() to + # return the integer value of that digit, which we then add to total. + for character in text: + if character.isdigit(): + total += int(character) + + # After adding together all the digit values we can return the total + return total + +# Returns the sum of the digits in the string text using a list comprehension +def sum_digits2(text): + + return sum([int(c) for c in text if c.isdigit()]) + + # The list comprehension [int(c) for c in text if c.isdigit()] produces a + # list. Each character 'c' in the string text is checked to see if it is a + # digit using isdigit(), and ONLY if it is a digit is the character + # converted to an integer value using int() and included in the produced + # list as an item. + # + # We then use the built-in sum function to return the sum of the numbers + # in this list, which we then return from the function as the sum of all + # digits in the string text. + + +# Test string +test_string = "A12,X 53c2" + +# Test the first function +digit_sum = sum_digits(test_string) +print(digit_sum) + +# Test the second function +digit_sum = sum_digits2(test_string) +print(digit_sum) \ No newline at end of file From 4a348c34b95695b69cc2002ec53bd0bd1d3f04cf Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:01:11 -0400 Subject: [PATCH 056/101] shuffle the lines of a file --- shuffle_file_lines.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 shuffle_file_lines.py diff --git a/shuffle_file_lines.py b/shuffle_file_lines.py new file mode 100644 index 0000000..7fb4ba2 --- /dev/null +++ b/shuffle_file_lines.py @@ -0,0 +1,36 @@ +################################################################################ +# +# Program: Shuffle The Lines Of A File +# +# Description: Program to shuffle the lines of a file using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=rjty0sSrFZc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Used to randomize the order of the lines in a file... +import random + +# Prompt the user for the filename for which they want to shuffle the lines, +# store the string entered into filename. +filename = input("Filename: ") + +# Open the file with the given filename for reading, use the file object to +# read the lines of the file. The readlines() method will return the lines of +# the file stored as strings in a list, which we store into lines. +with open(filename) as file: + lines = file.readlines() + +# The shuffle function of the random module will randomly re-arrange the +# strings stored in the random list, effectively randomly shuffling "the lines +# of the file". +random.shuffle(lines) + +# Open the same file for writing (i.e. writing mode, where what we write to +# the file will replace the existing content of the file). We use the +# writelines() method of the file object to write the lines of the file +# BACK TO the file, but this time in their new shuffled order. +with open(filename, "w") as file: + file.writelines(lines) \ No newline at end of file From 9ac73e451d7c624247673715f5e7aad6329bcced Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 11 Apr 2024 18:33:31 -0400 Subject: [PATCH 057/101] convert inches to feet and inches --- inches_to_inches_and_feet.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 inches_to_inches_and_feet.py diff --git a/inches_to_inches_and_feet.py b/inches_to_inches_and_feet.py new file mode 100644 index 0000000..3d4d71a --- /dev/null +++ b/inches_to_inches_and_feet.py @@ -0,0 +1,30 @@ +################################################################################ +# +# Program: Convert Inches To Inches and Feet +# +# Description: Program to convert a total number of inches to the equivalent +# number of feet and inches using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=N0Q9IwTGDTI +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user to enter the total number of inches. The input() function +# will prompt the user with the text "Inches: ", it will return the string the +# user enters, and int() will convert that string to an integer value which we +# store into total_inches. +total_inches = int(input("Inches: ")) + +# The built-in divmod() function will return the quotient and remainder of +# dividing total_inches by 12. The quotient will be the number of feet (as +# there are 12 inches in a foot) and the remainder will be any inches left +# over after accounting for the number of feet. The divmod() function returns +# a tuple, and we store each of the two values into the tuple into the +# variables feet (quotient) and inches (remainder). +feet, inches = divmod(total_inches, 12) + +# Output the total number of feet and inches (note that by default print() +# will separate the values it outputs by once space). +print(feet, "feet", inches, "inches") \ No newline at end of file From 2048aaca13f3a132bcdb3bda61d6b94d1cf82488 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:11:12 -0400 Subject: [PATCH 058/101] Monty Hall Problem Simulation --- monty_hall_simulation.py | 169 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 monty_hall_simulation.py diff --git a/monty_hall_simulation.py b/monty_hall_simulation.py new file mode 100644 index 0000000..214add8 --- /dev/null +++ b/monty_hall_simulation.py @@ -0,0 +1,169 @@ +################################################################################ +# +# Program: Monty Hall Problem Simulation +# +# Description: A program to simulate the Monty Hall Problem using Python, in +# particular to test out the different strategies of the player either sticking +# with their original pick OR switching their pick once the host opens a door +# to reveal the location of a goat. +# +# See the Wikipedia page for more details: +# +# https://en.wikipedia.org/wiki/Monty_Hall_problem +# +# YouTube Lesson: https://www.youtube.com/watch?v=YNysEWzeseg +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import random + +# The indexes of this list will represent doors with the value at that index +# representing the result of opening the door +doors = ["goat", "goat", "car"] + +# We'll test out the two different strategies of the player either sticking with +# the door they originally picked OR switching doors. We'll play the game +# 'attempts' number of times and we should find when the player sticks with +# their original pick that they win 1/3 of the time but if they switch doors +# they win 2/3 of the time. +attempts = 100000 + + + +# STRATEGY #1 - STICK WITH THE ORIGINAL DOOR + +# We'll keep track of how many times the player wins the game, initially 0 +wins = 0 + +# Test what happens when the player stays with their original door pick even +# after the host reveals a goat behind one of the other doors +for i in range(0,attempts): + + # Randomly re-arrange the contents of the doors list to represent the random + # placement of the goats and car behind the doors + random.shuffle(doors) + + # The player picks an index (i.e. door) either 0,1,2 in the doors list + pick = random.randint(0,2) + + # The host MUST reveal a door with a goat behind it, so we determine which + # indexes of the doors list contain a goat and store those into goat_doors + goat_doors = [] + for j in range(0,3): + if doors[j] == "goat": + goat_doors.append(j) + + # The first two branches handle the cases where the player picked one of + # the doors with a goat behind it... in these cases the host MOST open + # the OTHER door with goat behind it, i.e. the only other door with a goat + # behind it. The last branch handles the case where the player picked + # the door with the car behind it, in that case the host can open either + # door with a goat behind it and so we use choice() to choose one + # randomly. + if pick == goat_doors[0]: + host_opens = goat_doors[1] + elif pick == goat_doors[1]: + host_opens = goat_doors[0] + else: + host_opens = random.choice(goat_doors) + + # For this strategy the player stays with their original choice and so + # the player win if this original 'pick' is where the car is, if so we + # increments wins to acknowledge another win has taken place. + if doors[pick] == "car": + wins += 1 + +# Output the win percentage which should be approx. 33% or 1/3 as the player +# chose 1 of the 3 doors at random and stuck with it and 1 out of the 3 doors +# has a car behind it. +print((wins/attempts)*100) + + + +# STRATEGY #2 - SWITCH DOORS AFTER THE HOST REVEALS A GOAT + +# Reset wins for testing the other strategy +wins = 0 + +# Test what happens when the player SWITCHES doors to the only remaining +# door after the host reveals a door which has a goat behind it... +for i in range(0,attempts): + + # Randomly re-arrange the contents of the doors list to represent the random + # placement of the goats and car behind the doors + random.shuffle(doors) + + # The player picks an index (i.e. door) either 0,1,2 in the doors list + pick = random.randint(0,2) + + # The host MUST reveal a door with a goat behind it, so we determine which + # indexes of the doors list contain a goat and store those into goat_doors + goat_doors = [] + for j in range(0,3): + if doors[j] == "goat": + goat_doors.append(j) + + # The first two branches handle the cases where the player picked one of + # the doors with a goat behind it... in these cases the host MOST open + # the OTHER door with goat behind it, i.e. the only other door with a goat + # behind it. The last branch handles the case where the player picked + # the door with the car behind it, in that case the host can open either + # door with a goat behind it and so we use choice() to choose one + # randomly. + # + # Now remember that above when the player made their random selection, + # there is a 1/3 chance they pick the door with the first goat, a 1/3 + # chance they pick the door with the other goat, and a 1/3 chance they + # pick the door with the car. + # + # As we can see below, in the first two branches of the if-elif-else + # structure, when the player has picked a door with a goat behind it, + # the host is going to open the OTHER door with a goat behind it. Each + # of these branches has a 1/3 chance of executing, and so taken together + # the player has a 2/3 chance that they have initially picked a door with + # a goat and the host is going to reveal the only other door with a goat + # behind it. SO in these two cases, which is 2/3 or 66% of the time, when + # the player switches their pick to the only other door, that door MUST + # contain the car! + # + # When the player does NOT initially pick a door with a goat behind it but + # instead picks the door with the car, this is covered by the else branch + # below, which should only execute/occurs 1/3 of the time. In this case + # the host will reveal one of the two doors with a goat behind it, and the + # player will switch from the door which has a car to the other door with + # a goat behind it, and they will lose. But this will only occur 1/3 of + # the time. + # + # THIS is why switching leads to a 2/3 probability of winning, and we can + # see it fairly cleanly when we look at this if-elif-else control structure + # knowing each branch is equally likely to execute and the first two MUST + # lead to the player winning (assuming they switch their pick to the only + # remaining door). + # + if pick == goat_doors[0]: + host_opens = goat_doors[1] + elif pick == goat_doors[1]: + host_opens = goat_doors[0] + else: + host_opens = random.choice(goat_doors) + + # Switch to the only remaining door. We determine the only remaining door + # by process of elimination. The three door have indexes 0,1,2, stored in + # all_doors. We remove the index the player initially picked as they will + # switch away from this pick, and we remove the index for the door the host + # opened as the player cannot open that door. The only index remaining in + # all_doors at index 0 must be the door that the player will switch to. + all_doors = [0,1,2] + all_doors.remove(pick) + all_doors.remove(host_opens) + switch_pick = all_doors[0] + + # We have the player open the door that they switched to and increment + # wins if this is the door with the car + if doors[switch_pick] == "car": + wins += 1 + +# Output the win percentage which should be 2/3 or 66% as discussed above +print((wins/attempts)*100) \ No newline at end of file From 05c5e2fe8a03f5d15d8ceb3ed29be533e02a2bfd Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:46:34 -0400 Subject: [PATCH 059/101] shuffle a string --- shuffle_a_string.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 shuffle_a_string.py diff --git a/shuffle_a_string.py b/shuffle_a_string.py new file mode 100644 index 0000000..7c18ac0 --- /dev/null +++ b/shuffle_a_string.py @@ -0,0 +1,30 @@ +################################################################################ +# +# Program: Shuffle A String +# +# Description: A program to shuffle a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=FmL0iAJRHDs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Imported so we can use the sample() function +import random + +# A test string +s = "PortfolioCourses.com" + +# random.sample(X,N) will randomly select N characters from the string X and +# return them in a list. We pass our string s as the first argument and the +# LENGTH of the string as the second argument (i.e. number of characters in +# the string), so that the function returns a list of all the characters in +# the string in a random order. We then use the string join method to join +# these list items together into a new string, separated by the empty string "" +# (i.e no separation between the list items), giving us a shuffled string. +# +shuffled = "".join(random.sample(s, len(s)) ) + +# Output the shuffled string +print(shuffled) \ No newline at end of file From 127760be1f2102c1b73af7dc0a95acd771af0283 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:34:15 -0400 Subject: [PATCH 060/101] convert seconds to days, hours, minutes & seconds --- convert_secs_to_days_hours_mins_secs.py | 55 +++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 convert_secs_to_days_hours_mins_secs.py diff --git a/convert_secs_to_days_hours_mins_secs.py b/convert_secs_to_days_hours_mins_secs.py new file mode 100644 index 0000000..76baf9f --- /dev/null +++ b/convert_secs_to_days_hours_mins_secs.py @@ -0,0 +1,55 @@ +################################################################################ +# +# Program: Convert Seconds to Days, Hours, Minutes and Seconds +# +# Description: Program to convert a total number of seconds into the equivalent +# number of days, hours, minutes and seconds using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ljJejG-Q21M +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user to enter the total seconds, convert the string the user enters +# that is returned by input() into an int value with int() and store it into +# total_seconds. We'll use a series of division operations done with divmod() +# to perform the conversion. +total_seconds = int(input("Seconds: ")) + +# If we divide the total number of seconds by 60 (the number of seconds in a +# minute) then the quotient will be the total number of minutes and the +# remainder will be the number of seconds left over after accounting for the +# number of minutes. +# +# e.g. 200,000 / 60 = 3,333 remainder 20 +# +# If we take that total number of minutes and divide it by 60 (the number of +# minutes in an hour) then the quotient will be the total number of hours and +# the remainder will be the number of minutes left over after accounting for +# the number of hours. +# +# e.g. 3,333 / 60 = 55 remainder 33 +# +# And if we take that total number of hours and divide it by 24 (the number of +# hours in a day) then the quotient will be the total number of days and the +# remainder will be the number of hours left over after accounting for the +# number of days. +# +# e.g. 55 / 24 = 2 remainder 7 +# +# So 200,0000 seconds is 2 days, 7 hours, 33 minutes, and 20 seconds + +# divmod() returns the quotient and remainder, so we perform the following +# divisions in the same pattern as the example above to obtain the equivalent +# number of days, hours, minutes and seconds +# +total_mins, secs = divmod(total_seconds, 60) +total_hours, mins = divmod(total_mins, 60) +days, hours = divmod(total_hours, 24) + +# Output the resulting days, hours, minutes and seconds +print(" days:", days) +print("hours:", hours) +print(" mins:", mins) +print(" secs:", secs) \ No newline at end of file From 67809a70b57621bdef205f1a81ad37ab2c0e033e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 3 May 2024 20:22:33 -0400 Subject: [PATCH 061/101] count the occurrence of a string in a file --- count_string_in_file.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 count_string_in_file.py diff --git a/count_string_in_file.py b/count_string_in_file.py new file mode 100644 index 0000000..c90d5c0 --- /dev/null +++ b/count_string_in_file.py @@ -0,0 +1,29 @@ +################################################################################ +# +# Program: Count The Occurrences Of A String In A File +# +# Description: Program to count the occurrences of a string in a file using +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=QqCmA_T62Mc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user for the filename of the file to open and the text string to +# count the occurrences of in that file +filename = input("Filename: ") +text = input("Text: ") + +# Open the file with the provided filename for read access +with open(filename) as file: + + # Read all the contents of the file, store them into contents + contents = file.read() + + # Count the occurrences of the string text in the file contents + text_count = contents.count(text) + + # Output the occurrences of the string in the file + print("Count:", text_count) \ No newline at end of file From b09d533f8e6214f379d4844767069e682631c42d Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 8 May 2024 16:59:18 -0400 Subject: [PATCH 062/101] append text to a file --- append_text.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 append_text.py diff --git a/append_text.py b/append_text.py new file mode 100644 index 0000000..a2b91de --- /dev/null +++ b/append_text.py @@ -0,0 +1,25 @@ +################################################################################ +# +# Program: Append Text To A File +# +# Description: Example of appending text to the end of a file using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=DveYpz8hU1U +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user for the file to append text to and store entered filename +# into filename +filename = input("File: ") + +# Prompt the user for the text to append to the file and store the entered text +# into text +text = input("Text: ") + +# Open the file with the given filename in APPEND mode due to using the second +# argument "a", then use the file object's write method to append the text +# to the file. +with open(filename, "a") as file: + file.write(text) \ No newline at end of file From 3e3366637a880f334969cebcc84dd541fb836ffb Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 29 May 2024 07:40:06 -0400 Subject: [PATCH 063/101] remove all punctuation marks in a string --- remove_punctuation_marks.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 remove_punctuation_marks.py diff --git a/remove_punctuation_marks.py b/remove_punctuation_marks.py new file mode 100644 index 0000000..d5321b2 --- /dev/null +++ b/remove_punctuation_marks.py @@ -0,0 +1,33 @@ +################################################################################ +# +# Program: Remove All Punctuation Marks From A String +# +# Description: Program to remove all punctuation marks from a string in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=zo8FEfBP2FA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import string + +# Test string with some punctuation marks +text = "Should, 'we' use; punctuation marks...?!" + +# The string module contains a punctuation string constant containing all the +# punctuation marks +print(string.punctuation) + +# The string method translate can use a translation table passed in an as +# argument that is created by the method maketrans to replace and remove +# characters in a string. To make the translation table, we pass in empty +# strings for the first two arguments as we don't need to replace any characters +# in the string (and that is what these arguments can help do), but we do pass +# the optional 3rd argument... a string of all the characters to remove, in +# this case, string.punctuation (i.e. all the punctuation marks). The +# translate method will produce a new string. +new_text = text.translate(str.maketrans('','',string.punctuation)) + +# Output the new string +print(new_text) \ No newline at end of file From fd3b71970c501000c8cb214482e485801f155f0b Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:55:04 -0400 Subject: [PATCH 064/101] count the words in a string --- count_words_in_string.py | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 count_words_in_string.py diff --git a/count_words_in_string.py b/count_words_in_string.py new file mode 100644 index 0000000..b67c06d --- /dev/null +++ b/count_words_in_string.py @@ -0,0 +1,58 @@ +################################################################################ +# +# Program: Count The Words In A String +# +# Description: Program to count the words in a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=iB_Y295lT9I +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import string + +# Return the count of the words in the string text +def count_words(text): + + # Filters out all punctuation marks in the original string. The translate() + # method will take text and return a new string created using the + # translation table created by str.maketrans(). The str.maketrans() method + # could be used to replace characters with other characters in the string + # but we pass in empty strings as the first two arguments as we aren't going + # to do this. We do pass in string.punctuation as the third argument, a + # string constant contained in the string module containing all punctuation + # mark characters. This optional third argument will have all the characters + # of this string (string.punctuation) removed from text. + # + # We remove these punctuation marks because we don't want something like a + # dash character '-' to be considered a word. + # + after = text.translate(str.maketrans('','',string.punctuation)) + + # We split the string wherever there are whitespace characters like ' ', + # '\n' and '\t' using after.split() which will give us a list of string + # items like: ['9', 'words', 'separated', ... and on ... ]. We don't want + # numbers like '9' to be considered a word. So we take this list and use + # it in a list comprehension, where we produce a new list containing only + # the original list items that are ONLY made up of alphabetic characters. + # The isalpha() string method will only return true if the string is only + # made up of alphabetic characters, and so we use this to do the filtering. + # + words = [word for word in after.split() if word.isalpha()] + + # Find the number of items in the list using len(), i.e. number of words + # in the string + total_words = len(words) + + # Return the word count + return total_words + +# Test string. Notably we don't want to consider '9' and '-' to be words, so +# our function is built to remove punctuation marks from the string, and to +# NOT consider portions of the string in-between whitespace characters to be +# words IF they contain non-alphabetic characters. +example = "9 words separated by spaces - but dashes are not words" + +# Output the word count +print(count_words(example)) \ No newline at end of file From 339a07b30f4bd84fe47a89923d3db8d4c56b48f3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:25:51 -0400 Subject: [PATCH 065/101] count the words in a file --- count_words_in_file.py | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 count_words_in_file.py diff --git a/count_words_in_file.py b/count_words_in_file.py new file mode 100644 index 0000000..557b0c6 --- /dev/null +++ b/count_words_in_file.py @@ -0,0 +1,65 @@ +################################################################################ +# +# Program: Count The Words In A File +# +# Description: Program to count the words in a file using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Xofj7X5ZoPc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import string + +# Return the count of the words in the file with the provided filename +def count_file_words(filename): + + # open the file for reading, file is an object which allows us to access + # the file + with open(filename) as file: + + # Read all file text and store into text as a string using read() method + text = file.read() + + # Filters out all punctuation marks in the original string. The + # translate() method will take text and return a new string created + # using the translation table created by str.maketrans(). The + # str.maketrans() method could be used to replace characters with other + # characters in the string but we pass in empty strings as the first + # two arguments as we aren't going to do this. We do pass in + # string.punctuation as the third argument, a string constant contained + # in the string module containing all punctuation mark characters. + # This optional third argument will have all the characters of this + # string (string.punctuation) removed from text. + # + # We remove these punctuation marks because we don't want something like + # a dash character '-' to be considered a word. + # + after = text.translate(str.maketrans('','',string.punctuation)) + + # We split the string wherever there are whitespace characters like ' ', + # '\n' and '\t' using after.split() which will give us a list of string + # items like: ['9', 'words', 'separated', ... and on ... ]. We don't + # want numbers like '9' to be considered a word. So we take this list + # and use it in a list comprehension, where we produce a new list + # containing only the original list items that are ONLY made up of + # alphabetic characters. The isalpha() string method will only return + # true if the string is only made up of alphabetic characters, and so + # we use this to do the filtering. + # + words = [word for word in after.split() if word.isalpha()] + + # Find the number of items in the list using len(), i.e. number of words + # in the string + total_words = len(words) + + # Return the word count + return total_words + + +# Prompt the user to enter a filename, store input value into entered_filename +entered_filename = input("File: ") + +# Output the returned word count for the entered filename +print(count_file_words(entered_filename)) \ No newline at end of file From da2b4d51be84537493dacc9c13e4e8db7f524a02 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:38:28 -0400 Subject: [PATCH 066/101] reverse the words in a string --- reverse_string_words.py | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 reverse_string_words.py diff --git a/reverse_string_words.py b/reverse_string_words.py new file mode 100644 index 0000000..b0cf417 --- /dev/null +++ b/reverse_string_words.py @@ -0,0 +1,94 @@ +################################################################################ +# +# Program: Reverse The Words In A String +# +# Description: Program to reverse the words in a string using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=wcZRSbtBzGc +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns a new string identical to text but with the words contained in the +# string text reversed +def reverse_words(text): + + # Keeps track of whether a word is currently being read + reading_word = False + + # The new string returned by the function which we'll build as we go + # though the text string + reversed_words_text = "" + + # A reversed version of the current word being read + current_word = "" + + # The string is read one character at a time, and as it is we keep track of + # whether a word is currently being read or not. We do this because if a + # word is currently being read, we'll build a reversed version of that word + # in current_word. When we reach the end of the word, we'll concatenate + # that reversed version of the word onto the new string reversed_words_text. + # + # We consider words to be made up of a sequence of 1 or more alphabetic + # characters (as detected using isalpha()) and non-alphabetic characters + # to be non-word characters. + # + for character in text: + + # If we are NOT currently reading a word AND we have an alphabetic + # character, this is the beginning of a new word. We set reading_word + # to True to recognize this and store this first character into + # current_word. + if character.isalpha() and not reading_word: + reading_word = True + current_word = character + + # If we ARE currently reading a word AND we have an alphabetic character + # then it must be the next character in this word. We concatenate it on + # to the front of the current_word string (which has the affect of + # reversing the word one character at a time). + elif character.isalpha() and reading_word: + current_word = character + current_word + + # If we ARE currently reading a word AND we have a non-alphabetic + # character then we have reached the end of the word. We set + # reading_word to False to recognize this, we concatenate the completed + # reversed word to the reversed_words_text string, and we also + # concatenate this next non-word character after the word. + elif not character.isalpha() and reading_word: + reading_word = False + reversed_words_text += current_word + current_word = "" + reversed_words_text += character + + # Otherwise we must not be currently reading a word and the character + # must not be alphabetic, as would be so in the ' ' character after + # the ',' in the string below. In this case we just concatenate the + # character to the reversed_words_text string. + else: + reversed_words_text += character + + # If the string ends with a word and not a non-alphabetic character (like + # the below string ends with 'words'), then the end of the word will not + # be detected with the else if block above which relies on detecting the + # first non-alphabetic character after the word (and in this case, there + # is none). So in the case that the string ends with a word, current_word + # will be non-empty after the for-loop runs, it will store the reversed + # version of that word, and we just concatenate that word to the + # reversed_words_text string. + # + # Note that in Python if the string current_word is NOT empty then the + # below condition evaluates to True (but if it IS empty it evaluates to + # False). + if current_word: + reversed_words_text += current_word + + # Return the string built above + return reversed_words_text + + +# Test the function with an example string and output the results +example = "A string, with several words" +reversed = reverse_words(example) +print(reversed) From 5bec579e005b55e66d647cbbbde8e082a12b8f1c Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:14:56 -0400 Subject: [PATCH 067/101] delete all lines in a file that contain a string --- remove_files_lines_containing_string.py | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 remove_files_lines_containing_string.py diff --git a/remove_files_lines_containing_string.py b/remove_files_lines_containing_string.py new file mode 100644 index 0000000..546fabc --- /dev/null +++ b/remove_files_lines_containing_string.py @@ -0,0 +1,34 @@ +################################################################################ +# +# Program: Delete All Lines In A File That Contain A String +# +# Description: Program to delete all lines in a file that contain a string. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Wsejkkv_tPg +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user for the filename and the string text +filename = input("File: ") +text = input("Text: ") + +# Open the file for reading. Use the resulting file object's readlines() method +# to read all the lines of the file, the method will return all the lines of the +# file as strings in a list. We then use a list comprehension to go through +# each line and ONLY include the line in the filtered list if the string text is +# NOT in the line. So all the lines that DO include this string will NOT be +# included in this new filtered list. +with open(filename) as file: + lines = file.readlines() + filtered = [line for line in lines if text not in line] + +# Open the file for writing with the "w" argument, which will cause the file to +# become blank until we write content to it. Loop through the lines in the +# filtered list and write each line to the file. Because we only write the +# lines NOT containing the string back to the file, we have effectively deleted +# the lines that DO contain the string from the file. +with open(filename, "w") as file: + for line in filtered: + file.write(line) \ No newline at end of file From 13890144fdd48c2e63966036782e3777c1ffcfd0 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:16:46 -0400 Subject: [PATCH 068/101] Delete remove_files_lines_containing_string.py --- remove_files_lines_containing_string.py | 34 ------------------------- 1 file changed, 34 deletions(-) delete mode 100644 remove_files_lines_containing_string.py diff --git a/remove_files_lines_containing_string.py b/remove_files_lines_containing_string.py deleted file mode 100644 index 546fabc..0000000 --- a/remove_files_lines_containing_string.py +++ /dev/null @@ -1,34 +0,0 @@ -################################################################################ -# -# Program: Delete All Lines In A File That Contain A String -# -# Description: Program to delete all lines in a file that contain a string. -# -# YouTube Lesson: https://www.youtube.com/watch?v=Wsejkkv_tPg -# -# Author: Kevin Browne @ https://portfoliocourses.com -# -################################################################################ - -# Prompt the user for the filename and the string text -filename = input("File: ") -text = input("Text: ") - -# Open the file for reading. Use the resulting file object's readlines() method -# to read all the lines of the file, the method will return all the lines of the -# file as strings in a list. We then use a list comprehension to go through -# each line and ONLY include the line in the filtered list if the string text is -# NOT in the line. So all the lines that DO include this string will NOT be -# included in this new filtered list. -with open(filename) as file: - lines = file.readlines() - filtered = [line for line in lines if text not in line] - -# Open the file for writing with the "w" argument, which will cause the file to -# become blank until we write content to it. Loop through the lines in the -# filtered list and write each line to the file. Because we only write the -# lines NOT containing the string back to the file, we have effectively deleted -# the lines that DO contain the string from the file. -with open(filename, "w") as file: - for line in filtered: - file.write(line) \ No newline at end of file From 81c2bb7401a4d66c792924811ac28edb45c12fa2 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:17:17 -0400 Subject: [PATCH 069/101] delete all lines in a file that contain a string --- remove_file_lines_containing_string.py | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 remove_file_lines_containing_string.py diff --git a/remove_file_lines_containing_string.py b/remove_file_lines_containing_string.py new file mode 100644 index 0000000..c6f3602 --- /dev/null +++ b/remove_file_lines_containing_string.py @@ -0,0 +1,34 @@ +################################################################################ +# +# Program: Delete All Lines In A File That Contain A String +# +# Description: Program to delete all lines in a file that contain a string. +# +# YouTube Lesson: https://www.youtube.com/watch?v=Wsejkkv_tPg +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user for the filename and the string text +filename = input("File: ") +text = input("Text: ") + +# Open the file for reading. Use the resulting file object's readlines() method +# to read all the lines of the file, the method will return all the lines of the +# file as strings in a list. We then use a list comprehension to go through +# each line and ONLY include the line in the filtered list if the string text is +# NOT in the line. So all the lines that DO include this string will NOT be +# included in this new filtered list. +with open(filename) as file: + lines = file.readlines() + filtered = [line for line in lines if text not in line] + +# Open the file for writing with the "w" argument, which will cause the file to +# become blank until we write content to it. Loop through the lines in the +# filtered list and write each line to the file. Because we only write the +# lines NOT containing the string back to the file, we have effectively deleted +# the lines that DO contain the string from the file. +with open(filename, "w") as file: + for line in filtered: + file.write(line) \ No newline at end of file From 483bf9876c1fc82064201b966ad7fbab53c967cc Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 22 Jun 2024 13:52:27 -0400 Subject: [PATCH 070/101] merge two sorted lists --- merge_sorted_lists.py | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 merge_sorted_lists.py diff --git a/merge_sorted_lists.py b/merge_sorted_lists.py new file mode 100644 index 0000000..740d5ac --- /dev/null +++ b/merge_sorted_lists.py @@ -0,0 +1,69 @@ +################################################################################ +# +# Program: Merge Two Sorted Lists +# +# Description: Program to merge two sorted lists using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=p3fBGZk_ctM +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns a new list containing the items of the sorted lists list1 and list2 +# merged together in sorted order. The function utilizes the fact that these +# two lists are already sorted to perform this operation more efficiently. +def merge_sorted_lists(list1, list2): + + # A new merged list will be built from scratch + merged = [] + + # We'll go through the items in the sorted lists one at a time using a loop + # to build the merged list. We'll use counter variable i to keep track of + # our position in list1, and counter variable j to keep track of our + # position in list2. We also find the length of each list so we can + # recognize when we reach the end of a list. + # + i, j = 0, 0 + len1, len2 = len(list1), len(list2) + + # Because list1 and list2 are sorted, i and j will begin by storing the + # index of the smallest item in each list, and as we increment i and j + # they will store the index of the NEXT smallest item in each list. The + # index that i and j store are the indexes of the "next smallest item" + # in each list. We go through the lists using i and j and each time we + # find the next smallest item in EITHER list and appending that item to + # the merged list (and then incremented the counter variable for the list + # from which the item was taken so that it now stores the index of the + # NEXT smallest item in that list). Eventually we will reach the end + # of one of these lists when i == len1 and or j == len2, at which point + # we can stop. + # + while i < len1 and j < len2: + if list1[i] < list2[j]: + merged.append(list1[i]) + i += 1 + else: + merged.append(list2[j]) + j += 1 + + # To finish the merged list we can just concatenate the remaining items + # from the other list which we did not reach the end of yet to the merged + # list. Because i and j keep track of "how far we made it" into each list + # we use the list slicing operator to (e.g. list1[i:]) to get a list made + # up of the remaining items from the index i on in list1 and from the index + # j on in list2. We then concatenate these to the merged list. Keep in + # mind that because either i == len1 or j == len2, in one of these cases + # the slicing operation is going to return an empty list as there are no + # more items remaining in the list from that index onwards. + # + return merged + list1[i:] + list2[j:] + + +# Test case sorted lists +l1 = [1,3,5,7,9] +l2 = [2,4,6,8,10] + +# Test the function and output the resulting merged list +merged = merge_sorted_lists(l1,l2) +print(merged) \ No newline at end of file From cff735c4ce2f88aed13d6c41a671cf39064a1555 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:54:38 -0400 Subject: [PATCH 071/101] loop through a list using a while loop --- while_loop_list.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 while_loop_list.py diff --git a/while_loop_list.py b/while_loop_list.py new file mode 100644 index 0000000..9e0ad17 --- /dev/null +++ b/while_loop_list.py @@ -0,0 +1,62 @@ +################################################################################ +# +# Program: Loop Through A List Using A While Loop +# +# Description: Program to loop through a list using a while loop in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=5oI5qWwn_xE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# An example list with 5 items of length 5 +data = [5,6,7,8,9] + +# We could use a for loop to loop through the items of the list (also called +# iterating over the items of the list). The for loop body will run for each +# item in the list in order, and each time it does item will be set to the next +# item in the list. +for item in data: + print(data) + +# We could instead use a while loop to loop over the items in the list. A +# while loop will run as long as some condition is true. Each item in the list +# 'data' is available at an index: +# +# ->i-> +# 0 1 2 3 4 <- indexes +# data = [5,6,7,8,9] +# +# We can begin a special variable 'i' called a "counter variable" off at the +# index 0 before the first loop iteration. We can then use 'i' to access the +# items of the list with data[i], so in the first loop iteration we access +# the first item in the list at the index 0. At the end of the loop body we +# can increment i by 1 using i += 1. In this way, with each loop iteration +# i will move in-order through the indexes of the list from 0 to 1 to 2 and +# so on. +# +# The length of the list is 5 which we can find by calling len() and passing +# it the list. We have the loop condition 'i < len(data)' to continue the +# loop so long as i < 5, i.e. we continue the loop so long as i has not yet +# reached the length of the list as the last item in the list will be +# accessible at the index len(data) - 1 == 4. +# +i = 0 +while i < len(data): + print(data[i]) + i += 1 + +# While it's generally preferable to use a for loop to loop through the items +# in a list, a while loop and counter variable can be very flexible. For +# example here we "skip over" the next item in the list if the item at +# the current index i is equal to 6, by incrementing the counter variable 'i' +# by 2 in this case (but by 1 otherwise). +# +i = 0 +while i < len(data): + print(data[i]) + if data[i] == 6: + i += 2 + else: + i += 1 \ No newline at end of file From e2573a57a5e9121863cfca6a6c98290b8918fff4 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:48:21 -0400 Subject: [PATCH 072/101] print the positive numbers in a list --- print_positive_list_numbers.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 print_positive_list_numbers.py diff --git a/print_positive_list_numbers.py b/print_positive_list_numbers.py new file mode 100644 index 0000000..5639813 --- /dev/null +++ b/print_positive_list_numbers.py @@ -0,0 +1,23 @@ +################################################################################ +# +# Program: Print The Positive Numbers In A List +# +# Description: Program to print the positive numbers in a list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=JYSyYm48KDA +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A positive number is a numbe greater than 0. Here we have a list of numbers +# with 4 positive numbers 67, 78, 33 and 82. +numbers_list = [-45,0,67,78,33,-45,82] + +# The for loop body will run for each number in the list from -45 to 82. Each +# time it runs 'number' will be set to the next number in the list. We check +# if the number is greater than 0 (i.e. if it is positive) using an if-statement +# and only output the number if it is positive. +for number in numbers_list: + if number > 0: + print(number) \ No newline at end of file From 364d94078615d502c70ad8914070d87d15ce8cf9 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:33:09 -0400 Subject: [PATCH 073/101] print the positive numbers in a list --- print_positive_list_numbers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/print_positive_list_numbers.py b/print_positive_list_numbers.py index 5639813..c117d3d 100644 --- a/print_positive_list_numbers.py +++ b/print_positive_list_numbers.py @@ -10,7 +10,7 @@ # ################################################################################ -# A positive number is a numbe greater than 0. Here we have a list of numbers +# A positive number is a number greater than 0. Here we have a list of numbers # with 4 positive numbers 67, 78, 33 and 82. numbers_list = [-45,0,67,78,33,-45,82] @@ -20,4 +20,4 @@ # and only output the number if it is positive. for number in numbers_list: if number > 0: - print(number) \ No newline at end of file + print(number) From 54277e959da0634c241d8c1cf0970b891e58a36a Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:34:46 -0400 Subject: [PATCH 074/101] print the negative numbers in a list --- print_negative_list_numbers.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 print_negative_list_numbers.py diff --git a/print_negative_list_numbers.py b/print_negative_list_numbers.py new file mode 100644 index 0000000..e31841b --- /dev/null +++ b/print_negative_list_numbers.py @@ -0,0 +1,23 @@ +################################################################################ +# +# Program: Print The Negative Numbers In A List +# +# Description: Program to print the negative numbers in a list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=tnWBGLEoveE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A negative number is a number less than 0. Here we have a list of numbers +# with 3 negative numbers -67, -23, and -82. +numbers_list = [5,-67,0,45,-23,-82,95] + +# The for loop body will run for each number in the list from 5 to 95. Each +# time it runs 'number' will be set to the next number in the list. We check +# if the number is less than 0 (i.e. if it is negative) using an if-statement +# and only output the number if it is negative. +for number in numbers_list: + if number > 0: + print(number) \ No newline at end of file From cf025cd40468687bb97c2d91675b0add3141eab8 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:38:09 -0400 Subject: [PATCH 075/101] count positive, negative & zero numbers in a list --- count_list_positives_negatives_zeros.py | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 count_list_positives_negatives_zeros.py diff --git a/count_list_positives_negatives_zeros.py b/count_list_positives_negatives_zeros.py new file mode 100644 index 0000000..28a5302 --- /dev/null +++ b/count_list_positives_negatives_zeros.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Count The Positive, Negative And Zero Numbers In A List +# +# Description: Program to count the positive, negative and zero numbers in a +# list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=x60vsih56fg +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A test list of numbers with 4 positive numbers, 3 negative numbers and 2 +# zero numbers. Where positive numbers are > 0, negative numbers are < 0 and +# zero numbers are = 0. +numbers_list = [5,0,-67,85,62,-43,0,1,-6] + +# Maintain "running counts" of the number of positive, negative and zero numbers +# in the list. Initialized to zero as before we begin counting the types of +# numbers have not found any number of any type yet. +positive_count = 0 +negative_count = 0 +zero_count = 0 + +# Loops through the list of the numbers in the list in order, with each loop +# iteration 'number' will be set to the next number in the list. We check +# to see if the number is positive, negative or zero, and increment the +# correct running count variable accordingly. When the loop has finished +# executed we will have counted all the positive, negative and zero numbers. +for number in numbers_list: + if number > 0: + positive_count += 1 + elif number < 0: + negative_count += 1 + else: + zero_count += 1 + +# Output the resulting counts +print("Positives:", positive_count) +print("Negatives:", negative_count) +print("Zeros:", zero_count) \ No newline at end of file From 10189f955bbe67305064beedff6aaa071dd7f3f6 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Wed, 3 Jul 2024 23:57:06 -0400 Subject: [PATCH 076/101] convert a decimal number to a binary number --- convert_decimal_to_binary.py | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 convert_decimal_to_binary.py diff --git a/convert_decimal_to_binary.py b/convert_decimal_to_binary.py new file mode 100644 index 0000000..e6f060d --- /dev/null +++ b/convert_decimal_to_binary.py @@ -0,0 +1,82 @@ +################################################################################ +# +# Program: Convert A Decimal Number To A Binary Number +# +# Description: Program to convert a decimal number to a binary number using +# Python. More specifically, this program implements an algorithm to convert a +# non-negative integer to its binary number representation. +# +# YouTube Lesson: https://www.youtube.com/watch?v=B_2Z97sqRQs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Conversion Algorithm: +# +# Repeat until the number is equal to 0: +# +# Divide the number by 2: +# - remainder is the next digit in the binary number +# - quotient is used as the number in next iteration + +# For example, converting 43 to binary using this algorithm looks like this: +# +# 43 / 2 = 21 remainder 1 +# 21 / 2 = 10 remainder 1 +# 10 / 2 = 5 remainder 0 +# 5 / 2 = 2 remainder 1 +# 2 / 2 = 1 remainder 0 +# 1 / 2 = 0 remainder 1 +# +# Where the remainder of the last division operation becomes the leading digit +# of the binary number, and the remainder of the first division operation +# becomes the last digit of the binary number. +# +# 101011----- +# / | \ | +# 32 + 8 + 2 + 1 = 43 +# + +# Continually prompt the user to enter a valid non-negative integer until they +# do, store the result into decimal +while True: + + # Prompts the user to enter the integer, converts the text entered by the + # user and returned by input() from a string to an int value and stores + # it into decimal + decimal = int(input("Enter A Non-Negative Integer: ")) + + # If decimal is a negative integer reminder the user the integer must + # be non-negative + if decimal < 0: + print("Integer Must Be A Non-Negative Integer") + else: + # Stops the loop once decimal is a non-negative integer + break + +# Stores the binary number, represented as a string of 1s and 0s +binary = "" + +# Implements the algorithm described above, repeatedly dividing the number by 2 +while True: + + # divmod() will return both the quotient and remainder of decimal / 2, we + # notably store the quotient back into decimal as we want the quotient of + # the previous division operation to become the new decimal number in the + # next division operation + decimal, remainder = divmod(decimal, 2) + + # We essentially "prepend" the next binary number digit onto the front of + # the binary number (represented as a string) using the string concatenation + # operation '+'. This will build the binary number in the correct order, as + # noted above the leading digit of the binary number will be the remainder + # of the last division operation. + binary = str(remainder) + binary + + # Stops the loop/algorithm when the quotient reaches 0 + if decimal == 0: + break + +# Output the resulting binary number +print(binary) \ No newline at end of file From e7435e44f46c3107a42568b5b4ad78bdcaea4020 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:55:06 -0400 Subject: [PATCH 077/101] check if a string is a binary string --- check_binary_string.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 check_binary_string.py diff --git a/check_binary_string.py b/check_binary_string.py new file mode 100644 index 0000000..2a81da0 --- /dev/null +++ b/check_binary_string.py @@ -0,0 +1,33 @@ +################################################################################ +# +# Program: Check If A String Is A Binary String +# +# Description: Program to check if a string is a binary string using Python. +# i.e. the program will check if the string is a binary number containing only +# '0' and '1' digits (characters). +# +# YouTube Lesson: https://www.youtube.com/watch?v=Z79zHhFb1So +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Prompt the user to enter a potential binary number, store the entered text +# as a string into the variable binary +binary = input("Enter Binary Number: ") + +# The all() function will return True if all the items in the list it is passed +# as an argument are True, otherwise it will return False. We construct a list +# using a list comprehension which will examine each character 'c' in the binary +# string. If that character 'c' is either '0' or '1' (i.e. is c in the string +# "01"), then we add a True item to the list being constructed for that +# character, otherwise we add a False item to the list. So the list built by +# the list comprehension will contain only True items ONLY if the string is +# made up of only '0' and '1' digits (characters). And thus the all() function +# will only return True in this case as well, allowing us to verify if the +# the string is a binary string or not! +# +if all([True if c in "01" else False for c in binary]): + print("Binary String") +else: + print("Not A Binary String") \ No newline at end of file From d003ca4fe20fb09929243f5bdc33d7b97edc92f2 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:31:15 -0400 Subject: [PATCH 078/101] convert a binary number to a decimal number --- convert_binary_to_decimal.py | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 convert_binary_to_decimal.py diff --git a/convert_binary_to_decimal.py b/convert_binary_to_decimal.py new file mode 100644 index 0000000..58d1a3f --- /dev/null +++ b/convert_binary_to_decimal.py @@ -0,0 +1,88 @@ +################################################################################ +# +# Program: Convert A Binary Number To A Decimal Number +# +# Description: Program to convert a binary number to a decimal number using +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=E0UoYzma13g +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# To convert a binary number to a decimal number we can sum the "weight" of the +# digits that are set to 1, knowing that each digit in the binary number +# is "weighted" an increasing power of 2. +# +# 101011 binary = 43 decimal +# +# 2^5 2^4 2^3 2^2 2^1 2^0 +# | | | | | | +# 32 16 8 4 2 1 +# | | | | | | +# 1 0 1 0 1 1 +# +# 32 + 8 + 2 + 1 = 43 + + +# This loop will continue so long as the user has not yet provided a valid +# binary number as input, i.e. a binary string made up of only the characters +# '0' and '1'. +while True: + + # Prompt the user to enter a binary number. The text the user enters will + # be returned by the input() function as a string, we convert that string + # to a list using list() and store it into binary. So if the user enters + # in the text 101011 binary will be set to a list of strings made up of + # one character each, i.e. ['1', '0', '1', '0', '1', '1'] + binary = list(input("Enter Binary Number: ")) + + # The all() function will return True if all the items in the list it is + # passed as an argument are True, otherwise it will return False. We + # construct a list using a list comprehension which will examine each string + # 'c' in the list 'binary'. If that string 'c' is either '0' or '1' (i.e. + # is c in the string "01"), then we add a True item to the list being + # constructed for that string, otherwise we add a False item to the list. + # So the list built by the list comprehension will contain only True items + # ONLY if the list 'binary' is made up of only the strings '0' and '1'. And + # thus the all() function will only return True in this case as well, + # allowing us to verify if the entered string is a binary string or not! + # + # If the string is a valid binary string we stop the loop using 'break', + # otherwise we remind the user all digits must be either '0' or '1'. + # + if (all([True if c in "01" else False for c in binary])): + break + else: + print("All digits must be either 0 or 1") + + +# We'll store the converted decimal number into decimal, which we initialize to +# 0 as we'll add the weight of each digit that is set to '1' to decimal one at a +# time by going through the list 'binary' one item at a time. +decimal = 0 + +# The loop with execute as many times as there are items in the list 'binary', +# i.e. or as many digits in our binary number. And as it does the counter +# variable i will go from 0, 1, ..., len(binary)-1, where len(binary) is the +# length of our binary number. These numbers in the range 0, 1, ..., 5 in +# the case of 101011 will be exactly the exponents of the powers of 2 for +# each digit in our binary number. +# +# With each loop iteration, we pop off the LAST digit in the list, so for the +# list ['1', '0', '1', '0', '1', '1'] we'll pop off 1, then 1, then 0, and so +# on. We then check if the digit is 1. If it is, we get the weight of that +# digit using pow(2, i), where i the exponent of the power of 2 for that +# digit, and we add that weight to the decimal number we are creating. +# +# When the loop is done we will have added the weight of all the relevant +# digits to decimal and the sum and conversion will be complete. +# +for i in range(len(binary)): + next_digit = binary.pop() + if next_digit == "1": + decimal += pow(2, i) + +# Output the converted decimal number +print(decimal) From 3ff4ecf546d1fea31bb5086cbf21bdb1719eb34e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:32:05 -0400 Subject: [PATCH 079/101] check if a string is a binary string --- check_binary_string.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check_binary_string.py b/check_binary_string.py index 2a81da0..fd4b4fc 100644 --- a/check_binary_string.py +++ b/check_binary_string.py @@ -25,9 +25,9 @@ # the list comprehension will contain only True items ONLY if the string is # made up of only '0' and '1' digits (characters). And thus the all() function # will only return True in this case as well, allowing us to verify if the -# the string is a binary string or not! +# entered string is a binary string or not! # if all([True if c in "01" else False for c in binary]): print("Binary String") else: - print("Not A Binary String") \ No newline at end of file + print("Not A Binary String") From 371ad522e9b2cb35f0d9f8a62884c054eda6e5a1 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:05:04 -0400 Subject: [PATCH 080/101] calculate the factorial of a number (using a loop) --- calculate_factorial.py | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 calculate_factorial.py diff --git a/calculate_factorial.py b/calculate_factorial.py new file mode 100644 index 0000000..ca5622d --- /dev/null +++ b/calculate_factorial.py @@ -0,0 +1,51 @@ +################################################################################ +# +# Program: Calculate The Factorial Of A Number +# +# Description: Program to calculate the factorial of a number using Python. For +# the definition of a factorial see: https://en.wikipedia.org/wiki/Factorial +# +# YouTube Lesson: https://www.youtube.com/watch?v=tDTQ1h40SwE +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# The factorial of a non-negative integer n is defined as the product of all +# positive integers between n an 1, with the factorial of 0 defined as 1. +# +# n! = n x n-1 x .. x 2 x 1 +# +# 5! = 5 x 4 x 3 x 2 x 1 = 120 +# +# 0! = 1 + +# The math module includes a factorial function +import math + +# Or we can create our own. This function returns the factorial of n by +# calculating the product of all integers between n and 1. It uses a +# loop and counter variable to go through all of these integers, building +# the product one multiplication at a time using 'product'. Notably +# the function will still work for 0! n=0 as product is set to 1 and the +# loop will not execute at all in this case so we simply return 1. +def factorial(n): + product = 1 + for i in range(1,n+1): + product *= i + return product + +# Prompt the user to enter n, convert the string into an int type value and +# store it into n +n = int(input("Enter n: ")) + +# Output an error message if n is not a non-negative integer, otherwise we +# call the factorial function to calculate the product and output the result +if n < 0: + print("n must be a non-negative integer") +else: + product = factorial(n) + print(product) + +# We could also use the math module's factorial function +print(math.factorial(5)) \ No newline at end of file From f14fb7120fa75f2054dd50b1d880e28c299f51fe Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:50:47 -0400 Subject: [PATCH 081/101] count occurrences of a list item w/o using count() --- count_list_item_occurrences.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 count_list_item_occurrences.py diff --git a/count_list_item_occurrences.py b/count_list_item_occurrences.py new file mode 100644 index 0000000..b6b7584 --- /dev/null +++ b/count_list_item_occurrences.py @@ -0,0 +1,33 @@ +################################################################################ +# +# Program: Count The Occurrences Of An Item In A List Without Using .count() +# +# Description: Program to count the occurrences of an item in a list without +# using the built-in .count list method in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ttJ5R5HzNw8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the number of occurrences of value in the list items_list +def count(items_list,value): + + # The function works by looping through each item in the list and checking + # to see if the item is equal to the value we're looking for it, if it is + # we increment a running count (total) of the number of occurrences of + # that value. By the the time the loop is done we'll have counted all the + # occurrences of the value and we return that count (total). + total = 0 + for item in items_list: + if item == value: + total += 1 + return total + + +# A test list +items_list = [2,5,7,9,3,5,2,6,8,2] + +# Test the function out, counting the occurrences of 2 in the list (3 total) +print( count(items_list, 2) ) \ No newline at end of file From c85eac67a6064d28d4fafaeb071a25c3066a8212 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 5 Jul 2024 17:33:59 -0400 Subject: [PATCH 082/101] count the number of even numbers in a list --- count_even_numbers_in_list.py | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 count_even_numbers_in_list.py diff --git a/count_even_numbers_in_list.py b/count_even_numbers_in_list.py new file mode 100644 index 0000000..9474d66 --- /dev/null +++ b/count_even_numbers_in_list.py @@ -0,0 +1,39 @@ +################################################################################ +# +# Program: Count The Number Of Even Numbers In A List +# +# Description: Program to count the number of even numbers in a list using +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=eScKNNcztEs +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the number of even numbers in numbers_list +def count_even(numbers_list): + + # An even number is an integer which is divisible by 2, i.e. i we take the + # number and divide it by 2 we should have a remainder of 0. The modulus + # operator % will give us the remainder of a division operation. + # + # We count the number of even numbers in the list by using a for loop to + # iterate over each item in the list (which we call 'number'). We use + # the modulus operator to check if the number is even by checking to see + # if the number divided by 2 gives us a remainder of 0. Only if the number + # is even do we increment a running count of the number of even numbers + # in the list (total_even). By the time the loop is done we will have + # counted all the even numbers in the list and we then return that count. + # + total_even = 0 + for number in numbers_list: + if number % 2 == 0: + total_even += 1 + return total_even + +# A test list with 4 even numbers: 2,6,4,10 +numbers_list = [2,6,7,9,3,4,10,11,15] + +# Test the function, output the return value +print(count_even(numbers_list)) \ No newline at end of file From bf6019a7f31babcbb9563395852b103e03024ff5 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 6 Jul 2024 07:28:01 -0400 Subject: [PATCH 083/101] count the even numbers in a list --- count_even_numbers_in_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/count_even_numbers_in_list.py b/count_even_numbers_in_list.py index 9474d66..4152a8e 100644 --- a/count_even_numbers_in_list.py +++ b/count_even_numbers_in_list.py @@ -14,7 +14,7 @@ # Returns the number of even numbers in numbers_list def count_even(numbers_list): - # An even number is an integer which is divisible by 2, i.e. i we take the + # An even number is an integer which is divisible by 2, i.e. we take the # number and divide it by 2 we should have a remainder of 0. The modulus # operator % will give us the remainder of a division operation. # @@ -36,4 +36,4 @@ def count_even(numbers_list): numbers_list = [2,6,7,9,3,4,10,11,15] # Test the function, output the return value -print(count_even(numbers_list)) \ No newline at end of file +print(count_even(numbers_list)) From 356cf8fd5931cdc81c842e29d414eb6d9849bc83 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 6 Jul 2024 07:28:19 -0400 Subject: [PATCH 084/101] count the odd numbers in a list --- count_odd_numbers_in_list.py | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 count_odd_numbers_in_list.py diff --git a/count_odd_numbers_in_list.py b/count_odd_numbers_in_list.py new file mode 100644 index 0000000..1e9124a --- /dev/null +++ b/count_odd_numbers_in_list.py @@ -0,0 +1,39 @@ +################################################################################ +# +# Program: Count The Number Of Odd Numbers In A List +# +# Description: Program to count the number of odd numbers in a list using +# Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=i1LmlxdogEY +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Returns the number of odd numbers in numbers_list +def count_odd(numbers_list): + + # An odd number is an integer which when divided by 2 will have a remainder + # of 1. The modulus operator % will give us the remainder of a division + # operation. + # + # We count the number of odd numbers in the list by using a for loop to + # iterate over each item in the list (which we call 'number'). We use + # the modulus operator to check if the number is odd by checking to see + # if the number divided by 2 gives us a remainder of 1. Only if the number + # is odd do we increment a running count of the number of odd numbers + # in the list (total_odd). By the time the loop is done we will have + # counted all the odd numbers in the list and we then return that count. + # + total_odd = 0 + for number in numbers_list: + if number % 2 == 1: + total_odd += 1 + return total_odd + +# A test list with 3 odd numbers: 3,5,9 +numbers_list = [3,5,4,8,6,10,2,9,12] + +# Test the function, output the return value +print(count_odd(numbers_list)) \ No newline at end of file From 6adc572bdcbab0ee7925f7a66c4d566393a5252e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 7 Jul 2024 07:46:32 -0400 Subject: [PATCH 085/101] count even and odd numbers in a list --- count_even_and_odd_in_list.py | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 count_even_and_odd_in_list.py diff --git a/count_even_and_odd_in_list.py b/count_even_and_odd_in_list.py new file mode 100644 index 0000000..a21d6f2 --- /dev/null +++ b/count_even_and_odd_in_list.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Count Even And Odd Numbers In A List +# +# Description: Program to count the number of even and odd numbers in a list +# using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=ttJ5R5HzNw8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Test list with 5 even numbers (2,4,8,20,6) and 4 odd numbers (5,11,13,15) +numbers_list = [2,5,4,8,11,13,15,20,6] + +# Program works by keeping a running count of the number of even numbers and +# odd numbers found in the variables even_count and odd_count. An even number +# has a remainder of 0 when divided by 1, an odd number has a remainder of 1 +# when divided by 2. So we have a for loop iterate over each number in the list +# where with each loop iteration 'number' will be set to the next number in +# the list. We then divide the number by 2 using the modulus operator % which +# provides the remainder of a division operation. And in the if branch we +# check to see if the remainder is 0 which would tell us we have an even number +# and we increment even_count to acknowledge we have found another even number, +# and if this is not the case then in the elif branch we check to see if +# dividing the number by 2 gives us a remainder of 1 which would tell us we have +# an odd number and we increment odd_count to acknowledge that we have found +# another odd number. By the time the loop is done we will have counted all +# the even and odd numbers in the list. +# +even_count = 0 +odd_count = 0 +for number in numbers_list: + if number % 2 == 0: + even_count += 1 + elif number % 2 == 1: + odd_count += 1 + +# Output the results +print("Even numbers:", even_count) +print("Odd numbers:", odd_count) \ No newline at end of file From 70c601acceb670ea99b3de9b46719f9846545e83 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 7 Jul 2024 07:47:09 -0400 Subject: [PATCH 086/101] count even and odd numbers in a list --- count_even_and_odd_in_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/count_even_and_odd_in_list.py b/count_even_and_odd_in_list.py index a21d6f2..0cb2c4c 100644 --- a/count_even_and_odd_in_list.py +++ b/count_even_and_odd_in_list.py @@ -5,7 +5,7 @@ # Description: Program to count the number of even and odd numbers in a list # using Python. # -# YouTube Lesson: https://www.youtube.com/watch?v=ttJ5R5HzNw8 +# YouTube Lesson: https://www.youtube.com/watch?v=CGSzvzi6W5w # # Author: Kevin Browne @ https://portfoliocourses.com # @@ -39,4 +39,4 @@ # Output the results print("Even numbers:", even_count) -print("Odd numbers:", odd_count) \ No newline at end of file +print("Odd numbers:", odd_count) From 1819ccabe4758da0a47bbd8ddfd399f02203423a Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:32:47 -0400 Subject: [PATCH 087/101] split a statement across multiple lines examples --- multiline_statements.py | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 multiline_statements.py diff --git a/multiline_statements.py b/multiline_statements.py new file mode 100644 index 0000000..269910f --- /dev/null +++ b/multiline_statements.py @@ -0,0 +1,68 @@ +################################################################################ +# +# Program: Multi-Line Statements +# +# Description: Examples of how to split a statement across multiple lines using +# Python. Explicit line joining using the line continuation character \ is +# demonstrated, as well as implicit line joining using expressions with +# parenthesis, square brackets and curly braces, and defining strings across +# multiple lines with \ and docstrings (triple quote strings). +# +# YouTube Lesson: https://www.youtube.com/watch?v=LJQ4vdI4S_4 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Python statements (or lines) are separated using newline characters (i.e. by +# hitting enter in a typical text editor) +joe_grade = 90 +nageeb_grade = 95 +mary_grade = 88 + +# We may want to split a statement across multiple lines for style reasons, +# perhaps if a statement becomes too long to fit within the width of the +# text editor. We can put a line continuation \ character at the end of the +# line and then continue the statement on the next line as below. +# +# Note that in the official Python documentation each line is referred to as a +# physical line and doing this with \ is called explicit joining of these +# physical lines into a single logical line. +# +# Also note that we can have absolutely no characters after the \ character. +# +sum_grade = nageeb_grade + joe_grade + \ + mary_grdae + +# We can also use parenthesis (), square brackets [] and curly braces {} +# in expressions to split a statement across multiple lines. +# +# Below we split the statement across multiple lines by wrapping the +# expression in parenthesis. +# +sum_grade = (nageeb_grade + joe_grade + + mary_grade) + +# A list with [] defined across multiple lines +numbers = [4, + 5, + 6] + +# A dictionary with {} defined across multiple lines +student = {"name" : "Muhammad", + "age" : 22} + +# Strings can be defined across multiple lines using \ +text1 = "A string \ +across multiple lines" + +# Note that the newline character before 'across...' is NOT in the above string +print(text1) + +# We can use a triple quote string (or docstring) if we wish to preserve +# newline characters +text1 = """A string +across multiple lines""" + +# Note how in this string we DO have the newline character before 'across'! +print(text1) \ No newline at end of file From 031d463595c2dab3c987dad3c7ea0d4162e680ac Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:20:17 -0400 Subject: [PATCH 088/101] slot machine game --- slot_machine.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 slot_machine.py diff --git a/slot_machine.py b/slot_machine.py new file mode 100644 index 0000000..1b143e4 --- /dev/null +++ b/slot_machine.py @@ -0,0 +1,51 @@ +################################################################################ +# +# Program: Slot Machine Game +# +# Description: A simple and fun slot machine game in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=d_LUoX8w8Hk +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import random + +# symbols for the slot machine spins +symbols = ["šŸ’", "šŸ‹", "šŸ””", "šŸ’Ž", "7", "šŸ€"] + +print("šŸŽ° Welcome to the Slot Machine! šŸŽ°") + +# Continue the game until the player declines to continue +while True: + + # choices() returns a list with 3 random items from the symbols list, BUT + # we can have repeats, e.g. 2 lemons 1 diamond, 3 cherries, etc. + spin = random.choices(symbols, k=3) + + # Output the results of the spin + print("\nSpinning...") + print(f"\n| {spin[0]} | {spin[1]} | {spin[2]} |") + + # Analyze the results (3 matches, 2 matches, none) and ouput a suitable + # message to the player + if spin[0] == spin[1] == spin[2]: + print("\nšŸŽ‰ JACKPOT! All three match!") + elif spin[0] == spin[1] or spin[0] == spin[2] or spin[1] == spin[2]: + print("\n✨ Two symbols match! Not bad!") + else: + print("\nšŸ™ No match. Try again!") + + # Prompt the player to check if they want to continue. We use strip() to + # remove any trailing or leading whitespace, and we use lower() to set all + # letters in the string to lowercase. This accounts for the player entering + # in leading or trailing space characters, or entering an uppercase Y. + # + # We use break to stop the loop if the player input was anything other + # than 'y'... + # + choice = input("\nPlay again? (y/n): ").strip().lower() + if choice != 'y': + print("\nThanks for playing! šŸŽ²") + break \ No newline at end of file From 38c1a69bd9b59be07cca0db17295de98377e94b7 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 10 Jul 2025 16:55:46 -0400 Subject: [PATCH 089/101] remove duplicate items from a list --- remove_list_duplicates.py | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 remove_list_duplicates.py diff --git a/remove_list_duplicates.py b/remove_list_duplicates.py new file mode 100644 index 0000000..667dda0 --- /dev/null +++ b/remove_list_duplicates.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: Remove Duplicate Items From A List +# +# Description: Approaches to remove duplicate items from a list in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=YH6jEuV_0fg +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Sample list with duplicates +my_list = [1,1,1,2,2,3,3,3,3] + +# We can convert the list to a set using set(), sets do not have duplicates and +# so duplicate items will be removed when we do so. We then convert the set +# back to a list to get the list with duplicates removed. The only issue with +# this approach is that the order of the items may not be perserved. +# +# unique_list = list(set(my_list)) + +# As of Python 3.7 we can use the fromkeys method of the dictionary data +# structure to create a dictionary with keys made up of the unique items of +# our list AND the order will be preserved. We can use list() to produce a list +# using this dictionary, where the keys of the dictionary will become the items +# of the unique list. +# +# unique_list = list(dict.fromkeys(my_list)) + +# We could manually build a list made up of the unique items of the original +# list by looping through each item of the original list and only appending it +# to the new list if it is not already in the new list. In this way, only +# unique items will be transfered over to the new list. +# +unique_list = [] +for item in my_list: + if item not in unique_list: + unique_list.append(item) + +# Output the resulting list with only the unique items of the original list +print(unique_list) \ No newline at end of file From f139d63c6fcd2669c47690f38aa1ed5441092189 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 10 Jul 2025 21:37:02 -0400 Subject: [PATCH 090/101] check if all list items are unique --- check_list_items_unique.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 check_list_items_unique.py diff --git a/check_list_items_unique.py b/check_list_items_unique.py new file mode 100644 index 0000000..60d5313 --- /dev/null +++ b/check_list_items_unique.py @@ -0,0 +1,26 @@ +################################################################################ +# +# Program: Check If All List Items Are Unique +# +# Description: Check if all list items are unique in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=uAQST2Psgn4 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list with a duplicate item - 5 +my_list = [1,2,3,5,4,5] + +# When we convert a list to a set with set() any duplicate items will be removed +# because set items MUST be unique. We can then check the length of the set and +# origina list using len(), if the list ONLY contained unique items then no items +# should be removed when it is converted to a set and the lengths should be the +# same. Otherwise the list must have contained at least one duplicate item, in +# which case we report that not all item in the list are unique. +# +if len(set(my_list)) == len(my_list): + print("All items in the list are unique") +else: + print("Not all items in the list are unique") \ No newline at end of file From 5436911dd3a901f971d46f2e888b879a80ff7dd2 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:22:44 -0400 Subject: [PATCH 091/101] remove the empty strings from a list --- list_remove_empty_strings.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 list_remove_empty_strings.py diff --git a/list_remove_empty_strings.py b/list_remove_empty_strings.py new file mode 100644 index 0000000..1355433 --- /dev/null +++ b/list_remove_empty_strings.py @@ -0,0 +1,24 @@ +################################################################################ +# +# Program: Remove Empty Strings From A List +# +# Description: Remove the empty strings from a list using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=QLYaiFdHbhU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list with a couple empty strings +strings = ["portfolio", "", "courses", "", "subscribe"] + +# The list comprehension [ ... ] produces a new list by checking every string +# 's' in strings, and "if s" is true then the string 's' is put into the new +# list. "if s" evalutes to False if the string is empty and True if the string +# is non-empty in Python, so only the non-empty strings will be in the new list! +# +new_strings = [s for s in strings if s] + +# Output the new list +print(new_strings) \ No newline at end of file From 66fa7f6185e7f0be2982d44e362593022d1d7eac Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:06:11 -0400 Subject: [PATCH 092/101] loop over a list in reverse --- loop_list_reverse.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 loop_list_reverse.py diff --git a/loop_list_reverse.py b/loop_list_reverse.py new file mode 100644 index 0000000..5c9efb4 --- /dev/null +++ b/loop_list_reverse.py @@ -0,0 +1,23 @@ +################################################################################ +# +# Program: Loop Over A List In Reverse +# +# Description: Loop over the items in a list in reverse using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=RCnA3BKzrgo +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Test list +fruits = ["apple", "banana", "pear"] + +# Loops over the items in the list in reverse. The reversed() function that is +# built-in to Python does not reverse the list or produce a new list, what it +# does is return an iterator that allows us to iterate over the items in the +# list in reverse. The for loop uses the iterator to iterate over the list +# items in reverse. +# +for fruit in reversed(fruits): + print(fruit) \ No newline at end of file From 9d717f069947c2b2dac4b9697b3735bde666998d Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 11 Jul 2025 15:13:25 -0400 Subject: [PATCH 093/101] flatten a list of lists --- list_flatten.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 list_flatten.py diff --git a/list_flatten.py b/list_flatten.py new file mode 100644 index 0000000..a652b6a --- /dev/null +++ b/list_flatten.py @@ -0,0 +1,24 @@ +################################################################################ +# +# Program: Flatten A List +# +# Description: Flatten a list of lists using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=9GKWwMbCRKw +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# A list of lists +nested = [ [1,2,3], [4,5], [7,8,9] ] + +# The list comprehension produces a new list by essentially looping over each +# sublist with 'for sublist in nested' and for each sublist looping over each +# item with 'for item in sublist'. The 'item' at the start of the list +# comprehension effectively places each of these items in the new list that is +# created. +flat = [item for sublist in nested for item in sublist] + +# Output the flattened list +print(flat) \ No newline at end of file From 9863675322650f56a3e719922734d43f4d0cef10 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sat, 12 Jul 2025 15:58:16 -0400 Subject: [PATCH 094/101] check if a sentence is a pangram --- pangram.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 pangram.py diff --git a/pangram.py b/pangram.py new file mode 100644 index 0000000..6cfbfb4 --- /dev/null +++ b/pangram.py @@ -0,0 +1,40 @@ +################################################################################ +# +# Program: Check If A Sentence Is A Pangram +# +# Description: Check if a sentence is a pangram using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=kypZMXGt3Zk +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import string + +# Returns True is the string s is a pangram and False otherwise. +# +# A pangram is a sentence containing the letters from a-z (case doesn't matter). +# +# We determine if the string is a pangram by making all letters lowercase (as +# case does not matter). We then turn the string into a set, which will give +# us back a set with each letter of the string 's' as an item/string, e.g. +# { 'T', 'h', ... }. Because sets cannot contain duplicates, this will have +# the effect of removing multiple occurrencs of characters, e.g. multiple o +# characters in the sentence below. +# +# The ascii_lowercase constant is made up of the characters from a-z. We +# convert this to a set, and then use the issubset function to compare the +# sets. The function will return True if all the items in the set built +# using ascii_lowercase (i.e. the letters from a-z) are found in the set +# built using our sentence, thus checking if all the letters from a-z are +# in the sentence. +# +def is_pangram(s): + return set(string.ascii_lowercase).issubset( set(s.lower()) ) + +# Famous pangram example +print( is_pangram("The quick brown Fox jumps over the Lazy Dog") ) + +# Not a pangram +print( is_pangram("The quick brown jumps over the Lazy Dog") ) From 5ef0e74d94309748501409ed6d5bc1a9b63c44e3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Mon, 14 Jul 2025 11:53:05 -0400 Subject: [PATCH 095/101] check if a string is an isogram --- isogram.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 isogram.py diff --git a/isogram.py b/isogram.py new file mode 100644 index 0000000..5c87570 --- /dev/null +++ b/isogram.py @@ -0,0 +1,40 @@ +################################################################################ +# +# Program: Check If A String Is An Isogram +# +# Description: Check if a sentence is a isogram using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=mYt3fmOxPl8 +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Checks if string s is an isogram and returns True if so and False otherwise +# +# A string is an isogram if it has no repeating letters from a-z (case +# insensitive, i.e. an 'A' and 'a' in a string would be considered a repeating +# letter). We don't consider non-letters characters like '-' or ' ' when +# considering a string to be an isogram or not. +# +# This function works by first producing the string s with all letters made +# lowercase using lower(). We then create a list made up of ONLY the letter +# characters in the string using a list comphrension. When we convert this +# list to a set using set(), any duplicate letters will be removed as sets are +# not allowed to have duplicate items. So if we compare the length of the list +# of letters to the length of the set of letters, they should be equal if the +# string is an isogram because no duplicates will be removed, but if the string +# is not an isogram at least one duplicate will be removed and the lengths will +# not be the same. The result of this comparison is used as the return value +# of the function. +# +def is_isogram(s): + low = s.lower() + letters = [char for char in low if char.isalpha()] + return len(letters) == len(set(letters)) + +# The firt two strings are isograms but the second is not so we should get back +# True, True and False as return values +print(is_isogram("Machine")) +print(is_isogram("Six-year-old")) +print(is_isogram("Alphabet")) \ No newline at end of file From cb3ae4b488565e39c8f625d00ee6a4d8128955fd Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 15 Jul 2025 15:13:06 -0400 Subject: [PATCH 096/101] simple digital clock for the terminal --- clock.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 clock.py diff --git a/clock.py b/clock.py new file mode 100644 index 0000000..e7c86e7 --- /dev/null +++ b/clock.py @@ -0,0 +1,45 @@ +################################################################################ +# +# Program: Create A Clock +# +# Description: Create a clock using Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=vb7KeINPMco +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import time + +# Continue until Ctrl-C is used to stop the terminal, then output Clock Stopped. +# +# We do this to exit the program more gracefully than the KeyboardInterrupt +# exception text that would appear on the terminal otherwise. + +try: + # Continually output the current time on the current line every second. + # + # strftime() will retrun the current time formatted as a string + # hours:minutes:seconds am/pm with hours set to 12-hour clock, this is + # done using the format string with the correct format specifiers: + # + # https://docs.python.org/3/library/datetime.html + # + # We then use an f string to help output the time to the terminal. We leave + # a couple spaces to make space for the terminals cursor. Instead of the + # default beahviour of print outputting a newline each time it outputs a + # string, we use end="/r" to output a carriage return character instead. + # This will set the cursor back to the beginning of the current line of the + # terminal, so that we overwrite whatever was there previously (the last + # current time, which each iteration of the loop). + # + # We use time.sleep(1) to pause the execution of the loop/program for one + # second, so that we output the time each second. + # + while True: + current = time.strftime("%I:%M:%S %p") + print(f" {current}", end="\r") + time.sleep(1) +except KeyboardInterrupt: + print("\nClock stopped.\n") \ No newline at end of file From 2b365e76d9d31d2bc4b700e3a0120a701b5469a9 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:01:08 -0400 Subject: [PATCH 097/101] extract emails from text --- extract_emails.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 extract_emails.py diff --git a/extract_emails.py b/extract_emails.py new file mode 100644 index 0000000..59dfe02 --- /dev/null +++ b/extract_emails.py @@ -0,0 +1,35 @@ +################################################################################ +# +# Program: Extract Emails From Text +# +# Description: Extract emails from text using a regular expresion in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=L7OXfdoH80I +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import re + +# Returns all email addresses found in text. +# +# Uses a pattern to extract all the email addresses from the text using the +# regular expression module findall function. Note that the pattern will not +# match 100% of email addresses due to edge cases, but should match for 99%+ of +# common email addresses. +# +def extract_emails(text): + pattern = r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+" + return re.findall(pattern, text) + +# Example text +text = """ + bla bla kevin@gmail.com more text joe.black@canada.ca more + text nageeb_ali@company.co.uk +""" + +# Test the function +emails = extract_emails(text) +for email in emails: + print(email) \ No newline at end of file From c27bef6dae9595bd7a8f0c11d920c73936b23c8e Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:57:56 -0400 Subject: [PATCH 098/101] rename a file --- rename_a_file.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 rename_a_file.py diff --git a/rename_a_file.py b/rename_a_file.py new file mode 100644 index 0000000..f0c7554 --- /dev/null +++ b/rename_a_file.py @@ -0,0 +1,32 @@ +################################################################################ +# +# Program: Rename A File +# +# Description: Rename a file using the os module's rename() function in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=KCn38p7xjFw +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import os + +# old and new file names +old_name = "file1.txt" +new_name = "new.txt" + +# Attempt to rename the file. The rename() function will throw suitable +# exceptions for different circumstances if it cannot succeed, which we can +# handle, in addition to a catch all case. +try: + os.rename(old_name, new_name) + print(f"Renamed '{old_name}' to '{new_name}'") +except FileNotFoundError: + print(f"File '{old_name}' not found.") +except FileExistsError: + print(f"A file named '{new_name}' already exists.") +except PermissionError: + print("Permission denied.") +except Exception as e: + print(f"An error occurred: {e}") \ No newline at end of file From 4239b859b2c857ff971072bdff272d7706d371b3 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 18 Jul 2025 12:15:55 -0400 Subject: [PATCH 099/101] dad joke generator --- dad_jokes.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 dad_jokes.py diff --git a/dad_jokes.py b/dad_jokes.py new file mode 100644 index 0000000..ac67268 --- /dev/null +++ b/dad_jokes.py @@ -0,0 +1,44 @@ +################################################################################ +# +# Program: Dad Joke Generator +# +# Description: Program to tell dad jokes using Python and the +# icanhazdadjokes.com API. +# +# YouTube Lesson: https://www.youtube.com/watch?v=09XUBRjOD2A +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Used to make HTTP requests +import requests + +# Request header for the request, ensures we get back JSON data in the response +request_headers = { + "Accept" : "application/json" +} + +# Continue to tell dad jokes until the user decides to stop +while True: + + # Makes the request to the API, using a GET verb and the request header + response = requests.get("https://icanhazdadjoke.com", + headers=request_headers) + + # If the response is not OK, exit using break to stop the loop + if response.status_code != 200: + print("\nSorry, I ran out of jokes. Dad brain!") + break + + # Otherwise output the joke by getting the response body using .json(), + # getting the value at the key 'joke' + print(f"\n{response.json()['joke']}") + + # Exit if the user decides to do so, again using break to stop the loop. + # We use lower() to make all letters in the string lowercase just in + # case the user enters in 'N' instead of 'n'. + user_input = input("\nAnother joke? (y/n): ").lower() + if user_input == 'n': + print("\nLater, alligator!") + break \ No newline at end of file From b48ab0d7158ad2255aaa503b3e7d150da277f336 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Fri, 18 Jul 2025 22:18:21 -0400 Subject: [PATCH 100/101] quiz game using json file for question/answer data --- quiz_game_json.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 quiz_game_json.py diff --git a/quiz_game_json.py b/quiz_game_json.py new file mode 100644 index 0000000..8baa6f4 --- /dev/null +++ b/quiz_game_json.py @@ -0,0 +1,78 @@ +################################################################################ +# +# Program: Quiz Game Using JSON File Data +# +# Description: Quiz game in Python which uses JSON file data for the multiple +# choice quiz question and answer data. +# +# YouTube Lesson: https://www.youtube.com/watch?v=V4hOC8RWpjU +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +import json +import random + +# Read the JSON data from a file named quiz.json, the load() function of the +# JSON module will read the data from the file and convert it to a Python list +# of dictionaries. +with open("quiz.json") as f: + quiz_data = json.load(f) + +# Shuffle the quiz questions for randomization +random.shuffle(quiz_data) + +# Keep track of the users score and current question +score = 0 +question_number = 1 + +# Question option labels... we could expand this list potentially +letters = ['A', 'B', 'C', 'D'] + +print("🧠 Welcome to the Multiple-Choice Quiz!\n") + +# Loop through each question +for question in quiz_data: + + # Present the question + print(f"Question {question_number}: {question['question']}") + + # Present the options with the labels + options = question['options'] + for i in range(len(options)): + print(f" {letters[i]}. {options[i]}") + + # Accept the user choice, use upper() and strip() to turn lowercase + # letters into uppercase and strip prefixed or postfixed whitespace + # characters for flexibility, e.g. " a" would become "A" + user_input = input("Your choice (A/B/C/D): ").upper().strip() + + # If the user entered a valid letter... + if user_input in letters: + + # Find the index of the letter A,B,C,D in the letters list + index = letters.index(user_input) + + # Then find the text for the option that was selected using the + # corresponding index + selected = options[index] + + # If the answer is correct or incorrect, output appropriate feedback + if selected == question['answer']: + print("\nāœ… Correct!\n") + + # Increment the score if the answer was correct + score += 1 + else: + print(f"\nāŒ Wrong! Correct answer: {question['answer']}\n") + + # Output error message if the input was not a valid letter + else: + print("\nāš ļø Invalid choice. Skipping question.\n") + + # Increment the question number for the next question + question_number += 1 + +# Let the user know how they did +print(f"šŸŽÆ Quiz complete! You scored {score} out of {len(quiz_data)}") \ No newline at end of file From 85f16c3934301326bced31359c8f90ef6a4ff412 Mon Sep 17 00:00:00 2001 From: Portfolio Courses <85077613+portfoliocourses@users.noreply.github.com> Date: Sun, 20 Jul 2025 15:35:21 -0400 Subject: [PATCH 101/101] enumerate for looping over iterables with counter --- enumerate.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 enumerate.py diff --git a/enumerate.py b/enumerate.py new file mode 100644 index 0000000..0d9a61a --- /dev/null +++ b/enumerate.py @@ -0,0 +1,42 @@ +################################################################################ +# +# Program: enumerate() Example +# +# Description: Demonstrate of using enumerate in Python. +# +# YouTube Lesson: https://www.youtube.com/watch?v=PO8QOxeU_No +# +# Author: Kevin Browne @ https://portfoliocourses.com +# +################################################################################ + +# Recipe steps, which are typically ordered 1,2,3,... +steps = [ + "Preheat oven to 350°F.", + "Mix flour and sugar.", + "Add eggs and stir well.", + "Pour into a baking pan.", + "Bake for 30 minutes." +] + +# Looping over an iterable like a list in Python is easy enough with a for loop +# +# for step in steps: +# print(step) + +# But if we also want a counter/index variable we might use len() and range() +# like this, which is considered less 'Pythonic' (i.e. the way to do things +# properly in Python). We're having to increment the counter before outputing +# the step, call len() and range(), and use counter as a list index now. +# +# for counter in range(len(steps)): +# print(f"Step {counter + 1}: {steps[counter]}") + +# Instead we can use enumerate() which gives us back an enumerate object, which +# provides the for loop with both an auto-incrementing counter AND the next +# item in the list/iterable with each loop body execution. It's like an +# iterable with a counter now. We can also modify the starting point of the +# counter from the default of 0 using the optional keyword parameter start. +# +for counter, step in enumerate(steps,start=1): + print(f"Step {counter}: {step}") \ No newline at end of file