top of page
Search

Introduction to Programming with Python

Updated: Oct 2, 2021


I was afraid of Programming not very long ago. But as it turned out, I got interested in Data Science and Machine Learning. Having chose this field, there was really no choice with me bu to take my fears heads on. I decided to learn computer programming, and as it turned out, there is nothing to fear about. There is no dearth of reading material(in fact, the opposite is true. There is so much of reading material that it is overwhelming.). There is so much abundance of content that it poses another challenge, where to start and what is the right path to tread.

That is where I am going to help you with. I will hold your hand and walk with you on this exciting journey to start a new chapter in your learning experience. Let's learn how to talk to your computer, which is essentially what Computer Programming is.


1 What is Programming?


We all have experienced the end result of computer programming. When we play our favorite games on mobile or computers, open any mobile application or computer software, take a digital image, see photos on any screen or even send an email. There are computer programs running in the background, doing all the work, which we never see.

Computer is an obedient servant, but not a very wise one. They understand exactly what we tell them, nothing more, nothing less. Hence, when we give them instruction (by way of programs), these instructions must be specific and sequential.

The most suited analogy I can think of is a recipe. Lets take an easy recipe to make a bread (chapati or baked bread, or both). There are only few ingredients like flour, water and yeast (in case of baking). Each ingredient must be in the specific proportion. You put one cup water instead of half cup and the dough is too runny to hold its shape. In the same way, the instructions we give to the computer must be specific in order to get the desired results. The computers are very literal. They try to execute our commands exactly. If we give them bad instructions, the commands may not run at all. Or worse, it can have bug or it can crash altogether.

The other characteristics of computer program is, they are sequential, just like the steps in a recipe. The order of the steps will determine the final product. What if, while making a chapati, we put it on fire directly, instead of heating them on hot plate (tava) for some time? They will simply break and lose shape. Similarly, What if the flour was first put in oven, and then water was added to make dough? The cooked flour will not make dough. Order of actions matters. The same thing can be said about programming. It's all about giving computers the right instructions and the correct sequence of steps to produce the desired result.

So, to recap, programming is how we communicate with the computer. It's characteristics are instructions that are specific and sequential. And just like a recipe, when we get our programs right, we get to enjoy the final product.


2 How does a computer program work?


In order to instruct the computer to do anything, the instruction must be written in form of a computer program. To write a computer program, you have to tell the computer step by step, exactly what you want it to do. The computer then runs or executes the program and follows it step by step, to complete the task.

When you are telling the computer what to do, you also tell it how to do it. This how is the computer algorithm.


2.1 Computer Algorithm

Definition: In computer science, an algorithm is a finite sequence of well-defined, computer-implementable instructions, typically to solve a problem or to perform a computation. Algorithms are always unambiguous and are used as specifications for performing calculations, data processing, automated reasoning, and other tasks.

In computer systems, an algorithm is basically an instance of logic written in software by software developers, to be effective for the intended target computer(s) to produce output from given input. An optimal algorithm would produce faster results than a non-optimal algorithm for the same purpose. That is why algorithms, like computer hardware, are considered technology.

Let me give you few examples of Algorithm, which will make it more understandable. Lets take a real life example first, and them computational examples.

Real life Example of algorithm

Write an algorithm of how to make tea. Ingredients are water, sugar, milk and tea leaves to make two cups of tea.

  • Step 1: Start

  • Step 2: Take a pan with one cup of water in it.

  • Step 3: Light the burner and put the pan on it.

  • Step 4: Bring the water to a boil.

  • Step 5: Add two table spoon sugar and two table spoon Tea leaves in the boiling water.

  • Step 6: Add one cup of milk to the boiling mixture.

  • Step 7: Boil the contents in the pan for one minute.

  • Step 8: Switch off the burner.

  • Step 9: Filter the tea leaves from tea using a sieve.

  • Step 10: Pour the tea in cups and serve it.

  • Step 11: Stop

Computation Example of algorithm

Write an algorithm of how to sum 2+2 to give 4 as result.

  • Step 1: Start

  • Step 2: Type 2 + 2

  • Step 3: Press Enter

  • Step 4: Stop

The algorithm are made of 3 kind of statements. Any combination of these 3 kinds can be present in an algorithm.

  1. Sequence Statements

  2. Selection Statements

  3. Looping or Iterating Statements

2.2 Sequence Statements

In these Programs, one statement is executed after the another, in a sequential manner.

The above two examples, making the tea and calculating 2+2, both are examples of Sequence statements. Lets take on more example.

Example Calculate age of a person given his year of birth.

  • Step 1: Start

  • Step 2: Take the year of birth and Store in YOB.

  • Step 3: Take the current year and store in CY.

  • Step 4: Subtract YOB from CY and save in Age.

  • Step 5: Print Age.

  • Step 6: Stop

2.3 Selection Statements

In these Programs, some part of the program is executed based on a certain condition being fulfilled or not. If the condition is fulfilled, computer will execute one part of the program, and if the condition is not fulfilled, the other part of the program is executed.

Example Write and algorithm to check if a person has fever or not. Condition is, its fever if temperature is above 99 Degree Fahrenheit.

  • Step 1: Start

  • Step 2: Take the temperature and Store in TEMP.

  • Step 3: Check TEMP value. If its more than 99 Degree Fahrenheit, then go to step 4, otherwise go to Step 5.

  • Step 4: Print "He has Fever" and go to step 6.

  • Step 5: Print "He does not has Fever".

  • Step 6: Stop

2.4 Looping or Iterating Statements

In some programs, certain steps are executed again and again, based on conditional test. These repetitions are called iterations. The iteration is done using one or more looping technique. Hence this kind of programs are called Looping or Iterating statements.

Example Print all the numbers from 1 to 10.

  • Step 1: Start

  • Step 2: Store 1 in i.

  • Step 3: Check if value of i <= 10. If yes, go to step 4. If False, go to step 7.

  • Step 4: Print i.

  • Step 5: Increase the value of i by 1.

  • Step 6: Go to Step 3.

  • Step 7: Stop

In this example, the Steps 3 to 5 are iterated till the condition in the step 3 is fulfilled. Once it returns false, the loop ends.

2.5 Flowchart

The algorithms can be written in graphical form, using some symbols. This graphical representation is know as flowchart.

Flowcharts have some standard symbols for representation of functions. The same are tabulated below.



Let us see an example of flowchart.

Example Write the program to check if a number is even number or odd number.


In simple terms, Programming is ideas converted into 'step by step' instructions that a computer can understand. This step by step instruction, is called algorithm.

These algorithms and statements form a program. But computer is not going to understand these if the instructions (programs) are not formalized. The normal human language (If there is any such thing !) is very far from what the computer can understand. Hence we need to talk to the computer in it's own language. The language that the computer can accept.

Language is the keyword.


3 Human Languages vs Computer Languages

History of languages is as old as history of human civilization itself. It started as expression in form of cave drawings, then people started communicating by speaking specific words, which carried meaning. The languages used by us humans have evolved over time, but for a long long period, it remained verbal. Languages as medium of communication date back to more than 50,000 years, however we started writing only roughly 6000 years back.


I cannot doubt that language owes its origin to the imitation and modification, aided by signs and gestures, of various natural sounds, the voices of other animals, and man's own instinctive cries. — Charles Darwin, 1871. The Descent of Man, and Selection in Relation to Sex

In essence, we humans use language as a tool to express our thoughts, and communicate with each other. It's not only what we speak, but also what we express through voice modulations, Body language and of course the word (both verbal and writing).

So it was natural that when we created computers, and we wanted to talk to them, to give them instructions, we created some languages for this purpose. These languages are of two types.

  1. Machine Language (or Machine Code) - It is made of "0" and "1" and only computers understand this.

  2. Programming Language - These are the languages in which we humans give instruction to the computers (Machines).

The programming language is converted to machine language, so that computers understand human instructions (Programming language).

The question arises, Why do the computers need machine language? Why can't we talk to them in plain English (or any other human language)?

The reason lies in the lack of intelligence in computers. The computers are not intelligent beings like us. So they can not understand the nuances of advanced (or very high level) languages like humans. They can not understand that same words mean different things, when spoken in different tones or pitch or when combined with different body languages or facial expressions.




The computers understand only one language, that is Machine Language, written in binary digits of 0 and 1.

Now we understand, there is a gap. We speak only Human Languages (Natural Languages) and Computers only understand the machine language, so how do we pass instructions to them?


The Programming Language comes to our rescue. Programming Languages are written in Natural Human Languages, but they have strict syntax which makes them easily convertible to machine languages. There are two such converters commonly used for this task. They convert Programming Language to Machine Language.

  1. Compiler

  2. Interpreter

We will go in slight detail of how they work, and what they do. But before we go there, let us first understand the new language we got introduced to, the programming language a bit better.


3.1 What makes a language?

There are four characteristics which are common for all the languages, both Human and Programming.

  1. Alphabet: are a set of letters or symbols in a fixed order used to represent the basic set of speech sounds of a language. These are the most basic units of a complex language script. for example, the set of letters from A to Z.

  2. Vocabulary (or Dictionary): This is the totality of words (also called lexis) in any language, and the individual words have some meaning associated (as given in Dictionary) with them. Same words may have different meaning in different languages. For example, Bank of English language means cough in Dutch, and fart means good luck in Polish.

  3. Syntax: Syntax can also be called Sentence Structure. These are the rules, which tell you what combination of words make meaningful sentence. For example, My Name is Nilabh and Nilabh is my name are both correct syntax, but same words arranged as Name my Nilabh is doesn't convey any meaning, and hence wrong syntax.

  4. Semantics: Semantics comes from Ancient Greek: sēmantikós, meaning significant. It is the study of meaning, reference, or truth. Some sentences or phrases might be correct as per the rules of Syntax, but still either sound absurd or are not Truth. These are wrong semantics. For example, The boy stumbled and fell upon the road is correct, but what do you say about The road stumbled and fell upon the boy? This is correct in Syntax, but still not correct phrase, as its wrong in Semantics.

When you get to read the topic of Errors and its types in Python, you will come across Syntax Error and Semantic Error. I suggest you revisit the definitions and examples here once again at that time, as you will find these definitions of Language are ever so relevant in Python Programming Language (and in all other languages as well).

The Alphabet, Vocabulary, Syntax and Semantics are important feature of not only Natural Languages, but for all Programming languages as well. In fact, the rules are much more stricter in case of a Programming language, as compared to a Natural Language. That makes it somewhat difficult for non_programmer to write programs (which are logics written in Programming Language) whereas the same logic can be explained by the concerned person in her mother tongue (or maybe in many other languages as well).

This brings us to the next concern, which Programming Language is easy and which one is tough. To be honest, this is a very subjective question, and anyone who is fluent in one particular programming language, will find that one easier than the other programming languages(just like we are more comfortable in our mother tongue). So to settle this debate of programming languages, another term is used, High Level Language. A high level programming language is closer to the Natural language in writing, Understanding and interpretation than a Low Level Programming Language.

Python is a High Level Programming Language.

3.2 Programming Language

When we want to give instructions to a computer, we use Programming Language. There are hundreds of programming languages. Just like human languages, different programming languages have different rules (syntax) and meaning (semantics). We use different words, spelling and pronunciation for same words in different languages, similarly, same message in different languages is written very differently.

To show what and how things change with programming languages, I will show you one example, of same program or instruction, in different languages. You will notice the differences yourself.

"Hello World !" Program in C++

#include <iostream>int main() {
    std::cout << "Hello World!";
    return 0;
}

"Hello World !" Program in Java

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!"); 
    }
}

"Hello World !" Program in Python

print("Hello World !")

This is the simplest line of code in many languages, and hence used to showcase most of the time. Do not worry if you don't understand how the program is written or being executed, as we will come to that later. As for now, let's highlight the differences in syntax between languages.


First take a look at the programming language called C++. The image above will show how we would get the program to display Hello world when run. I want you to just notice the syntax used in the language. This consists of double quotes around the words Hello world, the use of a semicolon at the end of statements, and there's a return keyword right before a closing curly brace. All of these things are part of the syntax, or rules, of the C++ programming language.


The second example is in the programming language called Java. This is one of the most popular language used in mobile apps and other software developments these days. Notice how we would display Hello world! using Java. Notice the use of different syntax.

Also look at the same Hello World! program written in another programming language called Python. This is one of the most popular language in Data Science and Machine learning environment. Notice here the syntax is entirely different and much cleaner and simpler.

You must be thinking, why to complicate things with so many programming languages. Why not only one Programming language, which is used by all. The reason is, all programming languages have their own strength and shortcomings. Some are ideal for making websites, while some other are for making mobile applications, and some else are made to handle very complex mathematical calculations.

Regardless of the Programming language you chose, the computer doesn't understand it. The computer understands a very different language, and thats is called Machine Language. Machine language is very difficult for us to write in directly, because it's very complex, and comprises of mostly series of numbers. That is why we call these programming languages High level language, because they are closer to actual human languages. I will tell you shortly how the high level languages are converted to machine languages, and also, why you need not worry about it at all.

A program written in a high-level programming language is called a source code (in contrast to the machine code executed by computers). Similarly, the file containing the source code is called the source file.


3.3 Source Code

Source code is what programmers of all kind of programming languages write. It's the instruction we give to the computers, and its written in plain text. Plain text here means, there is no formatting like bold, italics or underlining. Hence the word processors like MS Word or Libre office or Google Docs are not the right softwares to write source codes. Because when we write in word processors, they by default insert other informations embedded in the text, like font type, indentation or bold/italics or any other formatting, which prevents them from being plain text. The source code has to be in actual characters.

Instead you can use text editors. In all windows PC, Notepad comes default. Mac users can use TextEdit. There are plenty other text editors available as well. So the point to remember is, Rich Text Format is not suitable for source code, only plain text is suitable.

Now are you ready to write your first Computer program or Source code?

We will write the same program that is used to teach the beginners since long time. The "Hello World!" program. We will use the python language syntax for now.

So open your Notepad or any text editor, and write this line

print("Hello World!")

Congratulations...

You have written your first Source code.


Source code can be one line or as simple as we just wrote, or it can be thousands of lines and extremely complex one. It depends on the need or the purpose of your program.

Now lets save our source code. Every Programming language has its file type or extension. By default, the text editor will save it as .txt or text file. But we will save it as the python extension, as we wrote the source code for python. The extension for Python file is .py. So lets save this file as Hello_World.py.

Now we know how to write our source code, and save it too. It's time that we need to learn how to translate it to the language that the computer understands, Machine Language.


3.4 How to Run the Source Code?

You just wrote your first source code. Now its time to run it.

Let's try the way we normally run the things in our computer. By double clicking on the file.

What happened?

The file simply opened as a text file, or in some cases it will ask for which program to use to open it, and if you use Notepad, again it will open as a text file. That is something you didn't expect. This is kind of anticlimax... Is it?

What is the point of a source code, which doesn't run?

The reason is simple. The code is not in the language the machine understands, and we have neither "compiled" nor "interpreted" the source code. You must be more confused, because you have never heard of any of these in computer programming parlance.

Let me explain.

There are three main ways to translate source code into machine code:

  1. Compile it

  2. Interpret it

  3. Combination of both

Compiling and Interpreting a source code is a very complex process, and we will not go into technical details of what goes beneath the hood. But I will certainly give you a fair idea of what these terms mean in simple language.

4 Compilation vs. interpretation

Computer Programmers are solving some problem with their programs. The solution (program in this case) can be differently thought and conceived, even for the same problem, by different programmers, based on their knowledge, experience, imagination and style.

However, the program has to be correct in these 4 respects.

  • Alphabetically – The alphabets(including all the symbols) used shall be written in the script recognized by the programming language.

  • Vocabularily – The words used in the program must be from the dictionary of the programming language. Each programming language has its own dictionary which the programmer needs to master. Fortunately, the dictionary of any programming language is much simpler and smaller than the dictionary of any natural language.

  • Syntactically – You must obey the syntax rules of the programming language.

  • Semantically – The program shall make sense, in respect to the problem it intends to solve.

Even one mistake in any of the above 4 aspects may cause the program to become completely useless.

Once you have written the program, which is free from any mistake or error, the final frontier remains, to convert it from the high level programming language to the low level machine language that the machine understands.

transforming a program from a high-level programming language into machine language:

COMPILATION - Translate the source code one time, and keep the translated file as an executable file (like .exe in windows). This translated file contains the machine code. Now this executable file (which differs based on operating system) can be circulated to be used as final product. The program which translates the source code is called a compiler.

INTERPRETATION - Translate the source code every time you want to run the program. The source code is not converted to any other format, and circulated in the same form as it was created. The end user who receives this source code also needs to interpret it every time he uses. The program which translates the source

you (or any user of the code) can translate the source program each time it has to be run; the program performing this kind of transformation is called an interpreter, as it interprets the code every time it is intended to be executed; it also means that you cannot just distribute the source code as-is, because the end-user also needs the interpreter to execute it.

Usually, a programming language is either Interpreted or Compiled.

4.1 Compiler

Compiler converts the source code to the machine code.

Lets take this example.

You write a letter to your friend back home in English, and that friend understands only French. So, you write the letter in English and use a translatorsoftware to translate the English letter into French Letter. In similar ways, the compiler translates or rather compiles the source code from high level programming language to machine language.




The above image is oversimplification of a very complex process, which we are not getting too deep into purposefully. That is beyond our scope for this book. If you are curious, you may look up for "compilers" online and you will get ample material to quench your thirst.

4.2 Interpreter

In computer programming, an interpreter is a computer program that directly executes instructions written in a programming language, without requiring them previously to have been compiled into a machine language program.

Taking forward the earlier analogy, the letter you wrote to your friend in English, who understands only Hindi. Instead of translating the letter to Hindi, you send the English letter to him. He then in turn, calls for an Interpreter to come to him, and explain the meaning of the letter to him, line by line. Every time, when wants to re-read the letter, he needs to call the interpreter to read the letter for him.

This is essentially what computer interpreters do: they process your source code each times its run, line by line, and it's required for the user to have the needed interpreter available on their machine.

Some programming languages are known as Compiled languages, like C, C++ and Objective C. Some other programming languages are Interpreted languages, like Python, PHP, Javascript etc.

So what happens when you write a program in Python?

When you have finished writing a program in Python, its like a text file on your computer. The source code or the program is in plain text format. Now you have to invoke or call your interpreter and the interpreter will read your code in the source file.

The interpreter reads the file like you read your book, left to right, and top to bottom. While reading the code, the interpreter also checks the source code for the rules, as we discussed earlier. If the code is correct, it keeps on moving forward(after executing it line by line along the way). It stops and the interpretation is interrupted the moment it finds any error. (It means your broke some rule !). You get an error message detailing what and where the error has occurred. This error message is helpful most of the time, and we will cover in later chapter how to read and understand the error messages.

It is also possible that a significant part of the code may be executed successfully before the interpreter finds an error. This is normal behavior in this execution model.

Now you know about both Interpreter and Compiler. Are you curious to know which one is better? And why a programming language is Interpreted or Compiled?


4.3 Compilation vs. interpretation - advantages and disadvantages


Advantages:

COMPILATION

INTERPRETATION

The execution of the translated code is usually faster;

you can run the code as soon as you complete it - there are no additional phases of translation;

only the user has to have the compiler - the end-user may use the code without it;

the code is stored using programming language, not machine language - this means that it can be run on computers using different machine languages; you don't compile your code separately for each different architecture.

the translated code is stored using machine language - as it is very hard to understand it, your own inventions and programming tricks are likely to remain your secret.

Disadvantages:

COMPILATION

INTERPRETATION

the compilation itself may be a very time-consuming process - you may not be able to run your code immediately after making an amendment;

don't expect interpretation to ramp up your code to high speed - your code will share the computer's power with the interpreter, so it can't be really fast;

you have to have as many compilers as hardware platforms you want your code to be run on.

both you and the end user have to have the interpreter to run your code.


4.4 What does this all mean for you?

  • Python is an interpreted language. Hence, it comes with the above-mentioned advantages and disadvantages.

  • As we are going to use Python language here, you need not bother about how to use the Compiler or Interpreter. When we install the Python software, the interpreter is also installed along-with. And it does the magic on its own, which we need not worry about.


5 Conclusion:

We got Introduced to the exciting world of communicating with the machines, by writing Programs for the Computers. We also saw that the algorithms and source codes, are ultimately simple concepts, and not some jargons to be afraid of. The comparison between Natural Languages and Computer programming languages highlight the core similarities between the way we talk to each other, and also, with the computers. We also had a glimpse on how our codes are translated for computers to understand, using interpretor and compiler. Python is interpreted, and you will be learning to use the Python Interpretor in coming chapters of this book.

Going forward, we will learn the Grammar of this new language, which will open doors for us, we didn't know existed. Python is the Key.


6 Key Learnings:

  • Programming: Programming is the process of creating a set of instructions that tell a computer how to perform a task. Computer programming is the process of designing and building an executable computer program to accomplish a specific computing result or to perform a specific task.

  • Algorithm: A process or set of rules and steps to be followed in calculations or other problem-solving operations, especially by a computer.

  • Flowchart: A flowchart is a picture of the separate steps of a process in sequential order. It is a generic tool that can be adapted for a wide variety of purposes, and can be used to describe various processes, such as a manufacturing process, an administrative or service process, or a project plan.

  • Programming Language: A programming language is a formal language comprising a set of strings that produce various kinds of machine code output. Programming languages are one kind of computer language, and are used in computer programming to implement algorithms.

  • Syntax: In linguistics, syntax is the study of how words and morphemes combine to form larger units such as phrases and sentences. In computer science, the syntax of a computer language is the set of rules that defines the combinations of symbols that are considered to be correctly structured statements or expressions in that language.

  • Semantics: This is the branch of linguistics and logic concerned with meaning. In computer science, the term semantics refers to the meaning of language constructs, as opposed to their form (syntax).

  • High Level Language: This refers to the higher level of abstraction from machine language. Rather than dealing with registers, memory addresses, and call stacks, high-level languages deal with variables, arrays, objects, complex arithmetic or boolean expressions, subroutines and functions, loops, threads, locks, and other abstract computer science concepts, with a focus on usability over optimal program efficiency.

  • Source Code: The Source Code is the list of human-readable instructions that a programmer writes, often in plain text format, when he is writing a program.

  • Machine Code: Machine code is a strictly numerical language which is designed to run as fast as possible, and may be considered as the lowest-level representation of a compiled or assembled computer program or as a primitive and hardware-dependent programming language.

  • Compiler: Compiler, computer software that translates (compiles) source code written in a high-level language (e.g., C++) into a set of machine-language instructions that can be understood by a digital computer's CPU.

  • Interpretor: In computer science, an interpreter is a computer program that directly executes instructions written in a programming or scripting language, without requiring them previously to have been compiled into a machine language program.


7 Exercise:


7.1 Testing Your Understanding:

  1. How is a programming language different from the languages we speak?

  2. What do you understand by Algorithm? How is it related to Flow Chart?

  3. Write an Algorithm to calculate the simple interest on a principle amount.

  4. What is a good program? Note down all the parameters you can think of.

  5. What is the language that computer understands?

  6. Compiler or Interpreter: Which one to use and Why?

  7. How do computers and Humans differ in Intelligence?

7.2 True or False:

  1. Computers are not intelligent beings as Humans.

  2. Source code and Machine code are same things and can be used interchangeably.

  3. Syntax deals with the true meaning of the phrase.

  4. Semantics is the study of meaning, reference, or truth .

  5. Computer can make decisions beyond the instructions given to them, based on changing environment.

  6. Computers understand the programming language directly.

  7. Some programming languages are compiled, some are interpreted and some have a mix of both.

  8. All the programs are sequentially executed.

  9. You prepare your resume in Plain Text using MS office Word Program.

  10. Compilers and interpreters are hardware based machines like a CD Drive.

7.3 Write your own Codes for this:

  1. Write an Algorithm to calculate the simple interest on a principle amount.

  2. Write an Algorithm to calculate the area of a Rectangle.

  3. Write an Algorithm to calculate the perimeter of a circle.

  4. Write an Algorithm to find all the prime numbers less than 100.

  5. Write an Algorithm to convert a sentence written in all Upper case to Sentence Case.

  6. Make a flowchart for making ice from boiled water, in your refrigerator.

  7. Make a flowchart for finding sum of all the even numbers less than hundred.

  8. Make a flowchart for calculating square of all the odd numbers between 1 to 15, both inclusive.

  9. Make a flowchart for writing the multiplication table of 3.

  10. Make a flowchart to calculate the compound interest.

7.4 Things to do:

  1. Make a list of all compiled and Interpreted languages. Find situation in which each of them will be more useful than the other.

  2. Create Algorithms for some of the common problems you see around you in your daily life. Prepare their flowchart as well.

  3. Do you think learning computer programming will help you automate some of your repetitive tasks? Prepare a list of such tasks and keep on trying to automate them as you keep on learning new concepts in this book.


47 views0 comments

Recent Posts

See All
bottom of page