{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Table of contents\n", "1. [What is Programming?](#programming)\n", "2. [What is a Program?](#program)\n", "3. [Algorithms](#Algorithms)\n", "4. [Divide & Conquer Principle](#divide_conquer)\n", "5. [Writing a good program](#good_program)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# What is Programming? \n", "Programming is simply about asking a computer to solve problems that are either too difficult or time consuming. To program successfully, we first need to identify our problem, break it down into simple steps, and finally communicate those steps to the computer in a language that it understands. By doing so, the computer can solve our problems more efficiently and effectively! We will use an example to illustrate this basic idea of programming. \n", "\n", "## Our first Programming example\n", "Let's imagine that you want to find the biggest number from a list of numbers. If the list only has few numbers, it is a simple task for you to find the largest number. However, if the list gets very big (for example with more than 100, or even 1000 numbers), it will take you much longer to find the biggest number. Thus, the computer is actually a great tool as it can repeatedly execute a simple task with accuracy and efficiency! In order to get the computer to do that, we need to overcome two challenges.\n", "\n", "### Challenge 1: Breaking the problem into simple steps\n", "The first challenge is that the computer can only execute very simple tasks. It cannot find the biggest number in the list when we command it to \"find the biggest number in the list\". We will need to create a _recipe_ that will list each tasks it has to execute to solve the problem logically and precisely. This \"recipe\" is commonly called an __algorithm__. The main difficulty in writing an algorithm is to break down the complex problem into simple problems that our computer can easily solve. This would be covered in the section __Divide & Conquer__.\n", "\n", "### Challenge 2: Coding\n", "The second challenge is that computers are no humans, so they do not understand our language (in this case English). If you want your computer to solve your problem, you need to tell it what to do in its language (such as __Python__, __R__, __Java__, __HTML__ etc). This is where __coding__ comes in. Coding is the action of translating an algorithm from our human language to the computer language." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# What is a Program?\n", "Now that we know what is Programming, we can understand what a Program is. A Program is a piece of code (a set of instructions for the computer to execute) that makes the computer solve our problem. Consequently, one can simply associate the term \"program\" with a programmer's work output.\n", "\n", "In our example, our Program will be a piece of code that enables the computer to find the biggest number from any given list of numbers. Given an __input__ (which in our example would be a list of numbers), the programm will solve the problem and give the solution as an __output__ (which in our example would be the biggest number of the list). \n", "\n", "![Program](imgs/02_program.png)\n", "\n", "## Combining Programs\n", "In complex problems, we usually need multiple programs to solve different parts of the problem we need to solve. It is very common to have a program inserted in another program, which helps to solve a bigger problem.\n", "![Program](imgs/02_combine_programs.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "# Algorithms\n", "An algorithm is a concrete set of rules used to solve a problem. From simple math like adding numbers to more complicated tasks like displaying content based on user input, an algorithm can be used to do just about anything. Algorithms are omnipresent in the programming world—they are a fundamental part of all programs; thus, every programmer needs to have a strong understanding of algorithms. \n", "\n", "## Creation of an Algorithm\n", "The creation of an algorithm is best done by following several steps:\n", "1. Understanding the problem: \n", " * Before any coding is done, the programmer should understand the problem he or she is tackling. This is best done by describing it in an easy to understand, human language.\n", " * In addition, the programmer should know the inputs and outputs and see the connection between them.\n", "\n", "2. Alternatives:\n", " * There is often more than one way to solve a programming problem.\n", " * The programmer should describe the various alternatives and then choose the best.\n", " \n", "3. Coming up with the solution:\n", " * Having chosen the best alternative, the programmer should then come up with a solution.\n", " * Helpful tools include diagrams and pseudocode.\n", " * Pseudocode is code “translated” to a human language. This can be very helpful as it bridges the gap between a human language and a programming language.\n", " \n", "4. Picking a language:\n", " * Once the programmer has come up with the solution, he or she must pick a language to write the program in.\n", " * For our purposes, this language will be Python.\n", " \n", "5. Debugging:\n", " * Having coded the program in a specific programming language, the programmer needs to debug.\n", " * This means he or she must ensure that everything functions as it is supposed to.\n", " * Most specifically, the algorithm must do what the programmer wants it to do.\n", " \n", "6. Documenting:\n", " * Lastly, the programmer should document the program well.\n", " * This means, for example, that he or she includes many useful comments and uses appropriate variable names.\n", " * The purpose of this is to make the program readable by any human. Consequently, any programmer can take a look at the program and is able to understand every line of code does.\n", " \n", "## Example of an Algorithm\n", "\n", "Let's go back to our first example and create our own algorithm.\n", "\n", "## Pseudocode\n", "As mentioned above, pseudocode serves to offer a more human friendly version of code. Hence, it is a useful tool to convert a thinking process into a sketch of the structure of the intended computer program so that the time taken to do actual coding can be reduced. This is best done by writing out the code in a way that resembles English as much as possible. An example of this can be seen below.\n", "\n", "Find the highest number in a set of numbers.\n", "\n", "```\n", "1. Create **list** = list of numbers \n", "2. Set a variable, **max**, equal to the first number of **list**\n", "3. for each **number** in the **list**:\n", "4. **if number** is higher than **max**:\n", "5. **max** takes the value of **number**\n", "6. print the **max**\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# Divide & Conquer Principle\n", "\n", "## What is this Principle about?\n", "The Divide & Conquer Principle is a versatile method applied universally to solve complex issues (Application fields include Politics and Military). The reason for this is because it is a great method to break down extremely complex issues to bite sized ones. Consequently, one can easily solve the big problem by finding solutions to the bite sized problems and then combining these answers to create a final solution. \n", " \n", "The visual below summarises the above explanation of the Principle.\n", "\n", "![Divide & Conquer](imgs/02_divide-conquer.png)\n", "\n", "## Application of the Principle to Coding\n", "\n", "In our example, our \"complex problem\" is finding the largest number from a given list of numbers. Some thinking is needed to break down the complex problem to simple problems, and smaller problems into even smaller problems... till the problems can be easily solved. Subsequently, we would need to order the set of problems in a logical fashion for the computer to understand. This process is documented in the mindmap below:\n", "\n", "![Divide & Conquer](imgs/02_divide-conquer.jpg)\n", "\n", "^*The reason that a function is needed is because we want to use the solution over and over again without having to implement the same coding algorithm as and when we want to utilise it. This cuts down a lot of time.*\n", "\n", "After this stage, we would need to write a pseudocode. There can be many versions to the pseudocode. Thus, you might find that the earlier psuedocode will differ slightly from the psuedocode shown below:\n", "```\n", "# Create a function that gives the largest number from the user's list of numbers\n", "\n", "Function maximum_number(list_of_numbers): \n", " \n", " 1. set a variable, largest_number, be the 1st number of the list \n", " 2. for every number in the given list of numbers: \n", " 3. if number is higher than largest_number: \n", " 4. largest_number takes the value of number \n", " 5. print largest_number \n", " \n", "Call out the function using the user's list to give us the final answer:\n", "\n", "maximum_number(list_of_numbers) \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the earlier stage, translate your pseudocodes into a coding language that the computer understands (which in our case is Python). Translation of the simplest tasks should be done first:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Create a function that gives the largest number from the user's list of numbers\n", "\n", "def maximum_number(list_of_numbers): # Create a function called maximum_number\n", " largest_number = list_of_numbers[0] # Create a variable that the list of numbers can be compared to\n", " for number in list_of_numbers: # Iterate each number in the list\n", " if number > largest_number: # The computer needs to compare adjacent numbers in the list\n", " largest_number = number # Replace the previous element with the larger element \n", " print(\"The largest number is: \",largest_number) # Computer prints the result of the largest element." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have the function, we can call it out anytime for any list of numbers." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The largest number is: 7\n", "The largest number is: 10\n" ] } ], "source": [ "# Call out the function using the user's list to give us the final answer\n", "\n", "maximum_number([2,4,6,7,5,3]) \n", "maximum_number([1,2,3,4,5,6,7,8,9,10])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "# Writing a good program\n", "\n", "## Three concepts to evaluate programs\n", "1. Correctness: The solution produces output that we wanted out of it - accuracy.\n", "2. Design: The implementation of the solution is done in a smart way where there are no redundancies, no copy and paste and steps are explicitly clear.\n", "3. Style: The code is made easily readable for a 3rd person that is new to the code.\n", "\n", "In every programming languages, there is a style guide for the language that proposes a standardized presentation of code so as to make it readable to any user. One style guide for Python would be the PEP 8 (https://www.python.org/dev/peps/pep-0008/). In the following section, we described some of its design and style principles that are recommended. \n", "\n", "## Four easily implementable practices for writing readable code:\n", "\n", "### Commenting & Documentation\n", "Code is more often read than written. When we write code, we write it for two primary audiences: our users and our developers (including yourself). Both audiences are equally important. If you’re having a problem reading your own code, imagine what your users or other developers are experiencing when they’re trying to use or contribute to your code.\n", "\n", "Comments are created in Python using the pound sign (#) and should be brief statements no longer than a few sentences. Comments though simple can be really useful when you have a long piece of code. \n", "\n", "There are generally two ways to comment on a code. The first way is to have block comments that follows your code either before/after the code. The other would be to have a inline comment. Lets have a new example to demostrate how commenting improves readability:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hammerhead\n", "great white\n", "dogfish\n", "frilled\n", "bullhead\n", "requiem\n" ] } ], "source": [ "# Define sharks variable as a list of strings\n", "sharks = ['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem']\n", "\n", "# For loop that iterates over sharks list and prints each string item\n", "for shark in sharks:\n", " print(shark)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more on commenting in Python, see the following: https://www.digitalocean.com/community/tutorials/how-to-write-comments-in-python-3\n", "\n", "### Consistent Indentation\n", "Indentation refers to the use of tabs and spaces at the start of your code to convey a program structure. In programming languages such as Python, indentation is used to determine the structure instead of using braces or keywords.\n", "\n", "Indentation improves the readability of your code. It is used to clarify the link between flow constructs such as conditions or loops, and code contained within and outside of them.You can see at a glance where the end of a code block is, rather than having to read each line until you find it. \n", "\n", "Let us demonstrate this example with the same code as before. Note that there are three levels of indentation: (1) under function (2) under the For loop (3) under the If statement. Note that if indentations are not done properly, Python would not be able to recognize the statements and would return an error. Let us take a look at our example:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def maximum_number(list_of_numbers):\n", "#--->Indentation under the function\n", " largest_number = list_of_numbers[0]\n", " for number in list_of_numbers:\n", "#------->Indentation under the For loop \n", " if number > largest_number:\n", "#----------->Indentation under the If statement\n", " largest_number = number\n", "#---> Note that this print is just in the function, but outside of the for loop\n", " print(\"The largest number is: \", largest_number)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Consistent Naming Schemes\n", "There are a lot of different possible naming styles. Naming styles can be used to distinguish between global/local variables, arguments, functions and classes. More importantly, naming conventions should be consistent throughout your program. This allows the reader to relate to the declared variables. Use function/variable names that are useful for the reader to understand the code rather than using ambigious names.\n", "\n", "### Limit Line Length\n", "Our eyes are more comfortable when reading tall and narrow columns of text. That is also the reason why newspaper articles have their content in narrow columns. When writing codes, try to avoid writing overly long horizontal lines of code unless there is a special situation where longer lines would improve readability. You could check out the PEP8 style guide for some guidelines on this as well - it proposes some maximum line length under its guidelines." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Use parentheses or slashes (\\) to break strings across multiple lines\n", "my_string = ('This is a very long string, so long that it will not fit into just one line' \n", " 'so it must be split across multiple lines.')\n", "# or\n", "my_string = 'This is a very long string, so long that it will not fit into just one line ' \\\n", " 'so it must be split across multiple lines.'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Example demonstrated on the code presented above\n", "In this example, we have two codes with the same function, written in different ways: one not so good while the other written in a better way. Lets take a look at the two codes written below and notice the differences:\n", "\n", "1. **Absence of comments** in the first code makes it harder for the the user to understand the block of code. As compared to the second example, we could determine quickly that it is a function that gives the maximum number as its output.\n", "2. **Absence of indentation** makes it difficult to differentiate between the flow constructs (Defining a function, For loop, If statement). This can potentially be messy when you have long lines of code and multiple functions/conditionals. \n", "\n", "3. **Variable names can be improved** instead of using ambiguous names such as \"nu\", \"z\" which leaves the user guessing. In the second example, we used names that spell out its own purpose to improve readability." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# ---------------Not so good---------------\n", "def nu(z):\n", " lar=z[0]\n", " for n in z:\n", " if n>lar:\n", " lar=n\n", " print(\"The largest number is: \", lar)\n", " \n", " \n", "# ---------------Good readable code---------------\n", "\n", "# Create a function called maximum_number\n", "def maximum_number(list_of_numbers):\n", "# Create a variable that the list of numbers can be compared to \n", " largest_number = list_of_numbers[0]\n", "# Iterate through each number in the list \n", " for number in list_of_numbers: \n", "# Compare adjacent numbers in the list and replace \n", " if number > largest_number: \n", " largest_number = number \n", " print(\"The largest number is: \", largest_number)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }