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