Python Tutorial – CS50

It is Thursday April 23, 2020 and in the Twin Cities of Minneapolis and St. Paul we are still in lockdown for the COVID-19 pandemic, but with some eased restrictions. The Federal Government has defined a very specific set of steps to gradually lift the quarantine in the country. Now it is up to the different States to apply the rules as they fit. If there is a recurrence then the state MUST go back to square one (full quarantine) and repeat the process somewhat slower in order not to overtax the healthcare system.

I received via email with the link to “Great economy, health care system prepared Europe’s powerhouse:  “How Germany has tackled coronavirus outbreak” article which talks about how Germany has handled the COVID-19 pandemic so far. The article was written by Frank Miles from Fox News.

Obviously, if a country is prepared for most expected and unexpected events they will do better than if they are not. I guess that is common sense which apparently is not so common. It is a fact that the past few administrations in the USA did not prepare the country for expected events by building stockpiles of some goods and manufacturing. It was more on the opposite; they took the allocated resources (USD) and made them disappear in different ways in order to get personal financial and political gains. It seems that the current administration is doing order of magnitudes better than previous ones. Hopefully the USA will come out of the pandemic stronger than before.

Let’s take a look at some numbers as illustrated in the following table:

Country Population Confirmed Death Counts
Germany 83,783,942 150,729 5,315
Italy 60,461,826 187,324 25,085
United States 331,002,651 855,250 47,974

I am not including China because the numbers and news coming out are not credible, it is just political propaganda. China started a cover up process back in November 2019 and it is still at it.

Now let’s look at the same set of number but in percentages of the total population:

Country Population Confirmed % Death %
Germany 83,783,942 0.180 0.0063
Italy 60,461,826 0.310 0.0414
United States 331,002,651 0.258 0.0145

You have probably aware of the saying “Lies, Damn Lies and Statistics”. The table uses total numbers which does not make much sense. The second table we use percentages of the population. In Death % column, Italy is the worse, followed by the USA and Germany is the best with about only half of the deaths in the USA.

How about in the Confirmed % column? The difference between countries may represent that the testing in Germany is not as good or as ubiquitous as in the USA; therefore we could infer that the USA is doing better.

One key value missing from the charts is the number of people from China visiting the respective countries and regions since November 2019. Such information would shed an enormous amount of light on how the pandemic has been spreading in different areas of the world.

OK, enough of COVID-19 and let’s get to the subject of this post. Since I am currently taking an edX course on-line for Python, I decided to watch the YouTube video PYTHON TUTORIAL! – CS50 Live, EP. 63. If you develop software in Python or if you watch videos to improve your technical skills, this video seems to be different in how is presented. If you watch it please let me know your thoughts.

The idea of the video is to present some very basic Python concepts which include regular expressions. To be honest with you, regular expressions are not the simplest thing to use regardless of the programming language. The example shown and the approach are quite good.

While watching the video I had Visual Studio Code (VSCode) and a command prompt open on my Windows 10 machine so I was able to stop the video and experiment with what was being said. No matter how simple things may be, I always like to experiment with them. It refreshes knowledge and seems that I always learn something new.

<<< Hello world!
<<< Hello world! >>> name: james bond
<<< Hello james bond
<<< Hello james bond

<<< Hello james bond - false

<<< firstName: James
<<<  lastName: Bond

<<< James Bond

<<< name ==>james bond<==

<<< James Bond - false

Like I said, I was watching and experimenting. I added, edited and deleted code during the process. In this example I used as input the string “james bond”.

<<< Hello world!
<<< Hello world! >>> name: john canessa
<<< Hello john canessa
<<< Hello john canessa

<<< Hello john canessa - false

<<< firstName: John
<<<  lastName: Canessa

<<< John Canessa

<<< name ==>john canessa<==

<<< John Canessa - true

In this pass I used the string “john canessa”.

<<< Hello world!
<<< Hello world! >>> name: jonathan charles canessa
<<< Hello jonathan charles canessa
<<< Hello jonathan charles canessa

<<< Hello jonathan charles canessa - false

<<< firstName: Jonathan
<<<  lastName: Canessa

<<< Jonathan Canessa

<<< name ==>jonathan charles canessa<==

<<< Jonathan Charles Canessa - false

In this last pass I used the string “jonathan charles canessa”.

I know that without looking at the code and not having information about it makes it hard to follow and understand. Hopefully the code and my narrative will make some sense.

import re

# **** ****
print('<<< Hello world!')
print("<<< Hello world!") print() # **** single or double quotes **** name = input(">>> name: ")
print("<<< Hello", name)
print('<<< Hello ' + name)
print()

# **** check if name is capitalized ****
if name.capitalize() == 'John':
    print("<<< Hello " + name + " - true")
else:
    print("<<< Hello " + name + " - false") print() # **** extract and display first and last names **** names = name.split() if len(names) >= 1:
    print("<<< firstName: " + names[0].capitalize())
else:
    print("<<< first name not specified") if len(names) >= 2:
    print("<<<  lastName: " + names[-1].capitalize())
else:
    print("<<< last name not specified")
print()

# **** ****
if names[0].lower() == 'john' and names[-1].lower() == 'canessa':
    print("<<< " + name.lower().title())
else:
    print("<<< " + names[0].capitalize() + " " + names[-1].capitalize())
print()

# **** ****
print("<<< name ==>" + name + "<==")
print()

# **** using search instead of match ****
if re.search(r'^John\s+(.+\s+)*Canessa$', name, re.IGNORECASE):
    print("<<< " + name.title() + " - true")
else:
    print("<<< " + name.title() + " - false")

The hello.py file starts by displaying the same string “Hello world!” using single and double quotes. As we know you can use either in Python. When using simple text they both behave quite similar. If you need to use quotes e.g., Mc Donald’s, then it is simpler, at least for me, to enclose strings with double quotes. I also work with C, C++, C# and Java so I am used to represent strings using double quotes.

In the next two print statements we see the difference when separating arguments using a comma or a plus sign. Note the additional space that is automatically displayed by the first statement.

We now look at checking if a name is or is not capitalized.

Given a full name we split it and display the first and last names. We also do a check to determine if both first and last names have been entered.

We then perform a check to determine is the user entered a specific name. In this case a variation of “john canessa”.

Finally we use a regular expression to determine if the name entered is “john canessa” or a variation by including a middle name. Based on my experience with regular expressions, you can think of so many cases such that one can spend hours or days experimenting with them.

>>> please enter a number: 5
❤ ❤ ❤ ❤ ❤
❤ ❤ ❤ ❤ ❤
❤ ❤ ❤ ❤ ❤
❤ ❤ ❤ ❤ ❤

In this example from a different file the user is prompted to display a Unicode character for a heart the specified number of times. In this case a 5 was entered.

# **** input returns a string; we need an integer value ****
num = int(input(">>> please enter a number: "))

# **** heart character (unicode) ****
heart_char = '❤'

# **** num must be an integer not a string ****
for i in range(num):
    print(heart_char + " ", end='')
print()

# **** print * num ****
heart_str = heart_char + " "
print(heart_str * 5, end='')
print()

# **** list comprehension ****
hearts = ['❤' for i in range(num)]

# **** unpack list and print elements ****
print(*hearts, sep = ' ')

# **** display hearts ****
print(' '.join(hearts))
print()

The file starts with a prompt to input the number of times the hearts are to be displayed. Note that the string had to be converted to an integer to be used as an argument to the range function.

The set of hearts are displayed in different ways. During the video the initial set was printed one heart per line. Then the idea was to print them on the same line. You can see the progressions if you decide to watch the video.

Microsoft Windows [Version 10.0.18363.778]
(c) 2019 Microsoft Corporation. All rights reserved.

# **** ****
C:\Users\johnc>dir
04/16/2020  02:31 PM    <DIR>          .
04/16/2020  02:31 PM    <DIR>          ..
09/22/2019  08:00 AM    <DIR>          .eclipse
03/15/2020  08:38 AM                59 .gitconfig
04/07/2020  10:38 AM    <DIR>          .p2
04/21/2020  08:07 AM    <DIR>          .pylint.d
09/22/2019  08:00 AM    <DIR>          .tooling
03/10/2020  03:53 PM    <DIR>          .vscode
03/10/2020  04:43 PM    <DIR>          3D Objects
03/10/2020  04:43 PM    <DIR>          Contacts
04/08/2020  07:59 AM    <DIR>          ContainsCloseNums
02/17/2020  03:52 PM    <DIR>          Documents
04/21/2020  07:55 AM    <DIR>          Downloads
09/22/2019  07:57 AM    <DIR>          eclipse
09/22/2019  07:59 AM    <DIR>          eclipse-workspace_0
03/10/2020  04:43 PM    <DIR>          Favorites
03/10/2020  04:44 PM    <DIR>          Links
03/10/2020  04:43 PM    <DIR>          Music
09/12/2019  04:36 PM    <DIR>          NCH Software Suite
04/23/2020  07:29 AM    <DIR>          OneDrive
03/10/2020  04:43 PM    <DIR>          Saved Games
03/10/2020  04:43 PM    <DIR>          Searches
03/10/2020  04:43 PM    <DIR>          Videos
04/22/2020  10:40 AM    <DIR>          workspace0


# **** ****
C:\Users\johnc>cd workspace0

C:\Users\johnc\workspace0>dir
04/22/2020  10:40 AM    <DIR>          .
04/22/2020  10:40 AM    <DIR>          ..
04/01/2020  08:57 AM    <DIR>          BST-Search
04/10/2020  11:34 AM    <DIR>          ComposeRanges
04/08/2020  08:04 AM    <DIR>          ContainsCloseNums
04/05/2020  08:32 AM    <DIR>          GraphBFS
04/21/2020  07:46 AM    <DIR>          Knights
04/17/2020  03:41 PM    <DIR>          MissingNumber
03/29/2020  08:30 AM    <DIR>          ORCost
04/19/2020  07:46 AM    <DIR>          RobotInAGrid
03/10/2020  04:24 PM    <DIR>          SortOnFrequency

# **** ****
C:\Users\johnc\workspace0>git clone https://github.com/JohnCanessa/Python-Tutorial-CS50.git
Cloning into 'Python-Tutorial-CS50'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 812 bytes | 7.00 KiB/s, done.

# **** ****
C:\Users\johnc\workspace0>dir
04/23/2020  11:11 AM    <DIR>          .
04/23/2020  11:11 AM    <DIR>          ..
04/01/2020  08:57 AM    <DIR>          BST-Search
04/10/2020  11:34 AM    <DIR>          ComposeRanges
04/08/2020  08:04 AM    <DIR>          ContainsCloseNums
04/05/2020  08:32 AM    <DIR>          GraphBFS
04/21/2020  07:46 AM    <DIR>          Knights
04/17/2020  03:41 PM    <DIR>          MissingNumber
03/29/2020  08:30 AM    <DIR>          ORCost
04/23/2020  11:11 AM    <DIR>          Python-Tutorial-CS50
04/19/2020  07:46 AM    <DIR>          RobotInAGrid
03/10/2020  04:24 PM    <DIR>          SortOnFrequency

# **** ****
C:\Users\johnc\workspace0>cd Python-Tutorial-CS50

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/
        hearts.py
        hello.py

nothing added to commit but untracked files present (use "git add" to track)

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git add hearts.py

C:\Users\johnc\workspace0\Python-Tutorial-CS50>git add hello.py

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   hearts.py
        new file:   hello.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git commit -m "having fun with Python"
[master 58913d2] having fun with Python
 2 files changed, 74 insertions(+)
 create mode 100644 hearts.py
 create mode 100644 hello.py

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/

nothing added to commit but untracked files present (use "git add" to track)

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1018 bytes | 1018.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To https://github.com/JohnCanessa/Python-Tutorial-CS50.git
   43716c7..58913d2  master -> master

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/

nothing added to commit but untracked files present (use "git add" to track)

# **** ****
C:\Users\johnc\workspace0\Python-Tutorial-CS50>git log
commit 58913d220afda34f7b814de36f0a9fe50618028a (HEAD -> master, origin/master, origin/HEAD)
Author: JohnCanessa <john.canessa@gmail.com>
Date:   Thu Apr 23 11:16:06 2020 -0500

    having fun with Python

commit 43716c7525642afbf0979fda3887a782f3948327
Author: John Canessa <8019504+JohnCanessa@users.noreply.github.com>
Date:   Thu Apr 23 11:10:22 2020 -0500

    Create README.md

Now that we are done, let’s create a GitHub repository, clone it, and add the Python code that I wrote while watching the YouTube video and getting it pushed to the repository.

The entire code for this project can be found in my GitHub repository.

If you have comments or questions regarding this, or any other post in this blog, or if you would like for me to serve of assistance with any phase in the SDLC (Software Development Life Cycle) of a project associated with a product or service, please do not hesitate and leave me a note below. If you prefer, send me a private message using the following address:  john.canessa@gmail.com. I will reply as soon as possible.

Keep on reading and experimenting. It is the best way to learn, refresh your knowledge and enhance your developer toolset!

One last thing, many thanks to all 673 subscribers to my blog!!!

John

Twitter:  @john_canessa

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.