import { addBanner, addArticle, addTitle, addHeader, addParagraph, addClassParagraph, addSubHeader, addOrderedList, addUnorderedList, addBlockquote, addInset, addInsetList, addInsetCodeListing, addInsetBulletList, addImageWithCaption, addButtonGroup, addSidebar, addSyntax, menu, global_menu } from '/scripts/import.js'; import { local_menu } from '/scripts/programming.js'; const heading = document.querySelector(".heading"); const global = document.querySelector(".global_menu"); const local = document.querySelector(".local_menu"); const sidebar = document.querySelector(".sidebar"); const main = document.querySelector(".main_content"); heading.append(addTitle("Programming Fundamentals")); heading.append(addParagraph("Sasha Vodnik - LinkedIn Learning - April 2024")); heading.append(addParagraph("BEYOND THE FUNDAMENTALS")); global.append(global_menu()); local.append(local_menu("programming_fundamentals")); main.append(addHeader("Understanding Collections")); main.append(addParagraph("Collections in a programming language offer a lot of benefits – we can group related pieces of information together and use a collective syntax to refer to them. For example, if we have 10 number variables we don't have to declare 10 variables called num1, num2, num3 and so on. We can just create an array of numbers and typically that would look something like")); main.append(addSyntax("num = [1,2,3,4,5,6,7,8,9,0];")); main.append(addParagraph("We can then access any of these 10 numbers with the array name and the index value of the number we want and typically, the first index value would be 0 so if we want the first value, we would use")); main.append(addSyntax("num[0]")); main.append(addParagraph("Most languages would have a length function so something like")); main.append(addSyntax("len(num)")); main.append(addParagraph("would return the number of elements in the array. This can be really useful if you want to iterate over an array without knowing in advance how big that array is. For example, a for loop in python will typically look like this")); main.append(addInsetCodeListing(["num = [1,2,3,4,5,6,7,8,9,0]", "", "for x in range (10):", " print(num[x])", "", "print(\"All done!\")"])); main.append(addParagraph("We know there are 10 numbers in the array so we can tell the loop to iterate 10 times and it will print out each array element and then print out a message to let you know that it is done!")); main.append(addParagraph("One problem with this is that if we get that number wrong, for example if we specify the loop with")); main.append(addSyntax("for x in range (9):")); main.append(addParagraph("this is a semantic error in that the syntax is correct but the meaning of the code is not what we intended and so the computer will do what we told it to, not what we wanted it to do.")); main.append(addParagraph("As I mentioned, there may also be times when you don't know what size the array is so you could create a variable to hold the length of the array and use that variable in your for loop or you can just plug the len function in to the loop in which case, the loop would be specified like this:")); main.append(addSyntax("for x in range (len(num)):")); main.append(addParagraph("and this has the same effect but it has the advantage that if we changed the number of elements in the array, we can still run the code without change the for loop and so our code will look like this:")); main.append(addInsetCodeListing(["num = [1,2,3,4,5,6,7,8,9,0]", "", "for x in range (len(num)):", " print(num[x])", "", "print(\"All done!\")"])); main.append(addParagraph("This also demonstrates another big advantage of collections, we can iterate over them in a loop. If we had used 10 different variable names for our 10 numbers, we would have need to print statements to display all of them like this.")); main.append(addHeader("Simple Collections")); main.append(addParagraph("There are lots of different types of collection and in some cases, whether something is a collection or not can be simply a matter of semantics but you will see certain types of collections like an array in most programming languages.")); main.append(addParagraph("The simplest form of collection in Python is a list and arrays in Python are lists but not all lists are arrays!")); main.append(addParagraph("What I mean by that is that an array can only consist of elements of certain data types whereas lists can contain elements of any data type so arrays are a subset of all possible lists and the syntax for creating a list is exactly the same as the syntax for creating an array.")); main.append(addHeader("Creating More Complex Collections")); main.append(addParagraph("Most programming languages have some form of data structure that allows you to specify a key value pair of some sort and in python that is a dictionary. The syntax is fairly similar and you declare it in pretty much the same way that you would an array but the collection itself is enclosed in curly braces rather than square brackets. The syntax is actually very similar (if not identical) to JSON and the keys and values are separated by a colon with each pair being separated by a comma.")); main.append(addParagraph("For example:")); main.append(addInsetCodeListing(["food = {", " 'appetizer': 'hummus',", " 'entree': 'gyro wraps',", " 'dessert': 'baklava',", "}"])); main.append(addParagraph("One of the more striking aspects of this in comparison to an array is the fact that we don't use square brackets to enclose the collection, we use curly braces.")); main.append(addParagraph("If we want to access the collection as a whole, we can refer to it by name so if we want to print out the entire dictionary, for example, we can do that with a command like")); main.append(addSyntax("print(food)")); main.append(addParagraph("If we want to access an individual item, the syntax here is a little weird but I guess it does at least make sense. It uses array-like syntax but rather than specifying an element, you would specify the key. So if food were an array or list, we would access the first element with a statement such as")); main.append(addSyntax("food[0]")); main.append(addParagraph("Since it is a dictionary and the first element has \"appetizer\" as its key, we access the first value with a statement such as")); main.append(addSyntax("food[\"appetizer\"]")); main.append(addParagraph("You can find more information on python dictionaries in w3schools.com under Python Dictionaries which has some usage examples, links to other collections and a mini quiz to test your knowledge of Python Dictionaries.")); main.append(addParagraph("One other feature of these dictionaries which is worth mentioning here is that they are mutable and this is true of other collection types in Python such as an array so we can add items to an existing dictionary or we can remove them.")); main.append(addHeader("Collections in Other Languages")); main.append(addParagraph("If you compare collections in python to collections in other programming languages such as C or Java, you will see that they are very similar but there are also some important differences. For example, collections, particularly arrays, are often immutable so if you are creating an array, you need to either know in advance how big the array needs to be or set it to some arbitrarily large. So that is a really useful feature.")); main.append(addParagraph("Another feature you find in other languages, but not python is that you often have to declare the type of an array. For instance, let's say that we want to create an array in C holding four integers. The syntax for that is something like")); main.append(addSyntax("int myNumbers[] = {25, 50, 75, 100};")); main.append(addParagraph("So that gives you an array of four numbers and these numbers are integers. We can later change the values held in the array, but this array will only ever hold 4 values and they will all be integer values.")); main.append(addParagraph("If we compare this to python, we can create an array with a command such as")); main.append(addSyntax("cars = [\"Ford\", \"Volvo\", \"BMW\"] ")); main.append(addParagraph("This is an array holding 3 string values but we can add a fourth element, let's say an integer with a command like:")); main.append(addSyntax("cars.append(1.2)")); main.append(addParagraph("The array now has 4 values, three string values and one integer value so this syntax is more flexible.")); main.append(addParagraph("You will find that in both cases, the type of syntax used is consistent with the philosophy behind the language and you will find other instances where the same thing tends to crop up. For example, unlike python or indeed, JavaScript, C is a strongly typed language so you can't work with a variable until you have declared it's type and once you have done that, you can't change the type.")); main.append(addParagraph("You might think that the approach taken by weakly typed languages such as python and JavaScript is clearly better because it makes variables easier to work with since you don't have to worry about the type. You can set it to any value you want to.")); main.append(addParagraph("The downside is that you can never be entirely sure what type of value a variable will hold, particularly where an application is being coded by a team and you might find different files are using the same variable name. The C approach means that you can be relatively certain that a variable holds a particular type of value so this can be a really big help in avoiding errors.")); main.append(addParagraph("Python does have an immutable collection type and that is tuple which is essentially an ordered, immutable list.")); main.append(addParagraph("You can generally find a lot of good information on the internet for these data types, including some handy pages on w3schools.com covering C Arrays, Python Arrays, JavaScript Arrays and Python Tuples.")); main.append(addParagraph("One final thing to bear in mind is that for the most part, collections are available in all languages although the terminology may not always be the same and we saw an example of this with arrays which are usually called lists in python. Another example we didn't really look at is the dictionary collection-type in which again you will find in most programming languages. However, to my knowledge, these are only called dictionaries in python. In other languages, you will see these being called maps, associative arrays or tables.")); main.append(addHeader("Challenge: Working with a Collection")); main.append(addParagraph("For this challenge, we will start off with two groups of variables as shown below.")); main.append(addImageWithCaption("./images/challenge_collections.png", "The starting point for our collections challenge")); main.append(addParagraph("The challenge is to convert these into a list called stars and a dictionary called peaks. We then want to output the name of the fourth nearest star and the name of the highest peak on the pacific plate. The solution and the output we get from running this is shown below:")); main.append(addImageWithCaption("./images/solution_collections.png", "The solution to the collections challenge.")); main.append(addHeader("Iterating Through Collections")); main.append(addParagraph("Iterating through the items in a collection is very common and is one of the ways in which you can use a loop. Typically, this would be a for loop or some variation of a for loop.")); main.append(addParagraph("The chief property of a for loop is that it is usually used when you want some code to be executed a fixed number of times so if you have a collection that is a list of spices, for example, you might want to print those out to the console or the screen or perform some other form of processing on them.")); main.append(addParagraph("Traditionally, a for loop has a control variable which acts as a loop-counter as well as the condition for stopping the loop. An example may make this clearer.")); main.append(addInsetCodeListing(["for (i = 0; I <= 10; i++) {", " print(spices[i]);", "}"])); main.append(addParagraph("This is a very simple example and this is a C style loop so let’s break it down. As you can see, most of the code is on the first line and after the for keyword we have the loop controls.")); main.append(addSyntax("i = 0;")); main.append(addParagraph("As you may have guessed, i is our control variable and we are giving that an initial value of 0. This can actually be any integer value but you will probably see this being given an initial value of 0 in most loops that you see, particularly if that loop is dealing with an array. This is because, as you might remember, elements of an array have an index value starting at 0.")); main.append(addSyntax("i < 10;")); main.append(addParagraph("This is the condition for stopping the loop and is very important if you don’t want your loop to run for ever – this, by the way, is called an infinite loop and it is very easy to accidentally create one! The loop will continue as long as this condition is true ")); main.append(addSyntax("i++")); main.append(addParagraph("This controls how the value of the loop-control changes in each iteration and is important because if the value didn’t change, i would always have a value of 0 so i < 10 will always evaluate to true and this would be an infinite loop. You can increase the value by any integer so it doesn’t always have to be 1, but the loop-control is essentially a counter so if you want it to count through every element in the array, it would be set to 1.")); main.append(addParagraph("This loop will execute 10 times and each time it does, it will print out an element from the array. Note that the second line is the body of the loop and it has just one statement and that is the print command. Notice also that we are using the value of the loop-control as the index value to access the array element.")); main.append(addParagraph("When the loop starts, 0 is the initial value and it is less than 10 so the body is executed and prints out the array element with an index value of 0. We are assuming that the array has 10 elements so we want the loop to run 10 times, each time accessing the element where i is the index value. The 10th element has an index value of 9 so when i has a value of 10, which is not less than 10, the loop will stop.")); main.append(addParagraph("This is simple enough but one thing to bear in mind is that this approach is perfectly fine when you have created the array yourself and therefore you know it’s size and can set the loop condition accordingly.")); main.append(addParagraph("A technique you will often see when creating a for loop is to use the size of the collection to work out how many times the loop has to run, although, as we will see in a moment, this is really redundant in some languages and that does include python. You can generally get the length of an array, for example, with a length function or some variation of it. As a reminder, the expression used to determine when the sample loop we saw earlier stops was")); main.append(addSyntax("i < 10;")); main.append(addParagraph("We can rewrite this as")); main.append(addSyntax("i < len(spices);")); main.append(addParagraph("Notice that we are iterating up to 1 less than the length and the reason for that should be apparent by now. If you recall, we start counting the elements of an array from 0 so if we have 10 elements in the array, these will be numbered from 0 to 9 so we want our loop to stop before it reaches 10. This is a very easy mistake to make and the consequences can vary depending on the language used but the chances are you will see a runtime error.")); main.append(addParagraph("There is a more modern variation on the for loop specifically designed to iterate over the elements of a collection and the syntax generally doesn’t specify a control variable, it simply loops once for each element in the collection. For example, in python, we can rewrite our for loop as a for in loop.")); main.append(addInsetCodeListing(["for i in spices: ", " print(i);"])); main.append(addParagraph("So that is a neater and more concise syntax and it just tells the interpreter to run this code once on each element in the array/list. Note that i is not a control variable in this example. It actually represents the element and that is why we are printing i in each iteration rather than the element with index value i.")); main.append(addParagraph("There are other variations on this as well but the principle is still the same.")); main.append(addParagraph("In addition to for loops, most modern languages offer a while loop and a do while loop and these operate on a different principle to the for loop. Rather than specifying a condition and how it changes, a whole loop simply specifies the condition that will cause the loop to terminate. Typically, the loop will iterate until some condition evaluates to false and it is up to the programmer to specify how the value specified in the condition changes.")); main.append(addParagraph("~A typical usage might be a menu where a user is expected to select an option where each possibility has a number between 1 and 3. The condition might be that some value is not equal to 1, 2 or 3 so the loop will continue until the user provides an appropriate value and will then execute the code appropriate to the chosen menu item.")); main.append(addParagraph("This is almost like specifying an infinite loop since it will continue iterating until the value is between 1 and 3.")); main.append(addParagraph("Actually, this example would probably be more suitable for a do while loop. These are both very similar to each other, the difference being that a while loop tests the condition before iterating through the loop and the do while loop tests it after. The significance of this is that the condition may be met before the loop executes.")); main.append(addParagraph("For a while loop, that means the code inside the loop is not guaranteed to run but the code in a do while loop will run at least once so for something like a menu where you want to be sure the options are displayed before a choice is made, the do while loop is a safer option.")); main.append(addParagraph("However, it is also worth pointing out that the different loop are really just a convenience designed to make coding a little easier. If you have a programming language that only provides one type of loop, you will still be able to use it to code anything that you could code with any of the loop types, but using a specific type of loop that suits the circumstances better is less prone to errors.")); main.append(addParagraph("Actually, if we wanted to be quite pedantic on this point, you don’t really need any type of loop since anything you can code with a loop can also be coded without. Again, a loop just makes the programmers life a little easier!")); main.append(addHeader("Using External Code")); main.append(addParagraph("Most, if not all modern programming languages allow you to use code that has been prewritten. You could think of these as extensions to the language. For example, you might have some code that you want to use many times. If you look at the menus at the top of this page, you’ll see that there is a menu covering subjects and if you navigate to another page on this site, you will see that menu (although not always in the same form as shown here.")); main.append(addParagraph("The second menu is slightly different. Again, you will see it on many of the pages on this site and sometimes it will look exactly the same as it does here. If you click on one of the items in this menu, this will take you to another page in the Programming Fundamentals collection of pages which is a group of pages related to the Programming Fundamentals Learning Path on LinkedIn Learning.")); main.append(addParagraph("Since these menus appear so often, it wouldn’t make much sense to code them on every page which is not only tedious but is also hard to change. For instance, if I wanted to change the first menu option to display Programming Fundamentals rather than just Fundamentals, I would have to change it on every page that uses the menu.")); main.append(addParagraph("You may be familiar with functions which allow you to write some piece of code and then call it whenever you need it to run. When you create a function and then run the code that includes the function, it won’t do anything because it’s just a declared function. To run it, you have to put a call to the function in your code somewhere.")); main.append(addParagraph("Now, if you put the function in a file, such as the file used to generate this page, it’s probably going to be more work than if you just coded it directly. A more sensible approach is to write it in another file and then import it into this one. This means that for any page that uses these menus, I just need to import the menu functions and I can then call them as if they were created somewhere in the file.")); main.append(addParagraph("Before I move on, I just want to mention the difference between these two functions. The first menu (which I refer to as the global menu) is fixed so the data needed to generate these links is hard-coded in the global_menu() function so I just have to call it with")); main.append(addSyntax("global.append(global_menu();")); main.append(addParagraph("This will call the function to generate the menu and append it to the HTML div with id global.")); main.append(addParagraph("You can see this in the image shown below.")); main.append(addImageWithCaption("./images/dreamweaver.png", "Part of the JavaScript code used to generate this page.")); main.append(addParagraph("As you can see, there is a similar call for the local menu but this includes a parameter.")); main.append(addSyntax("local.append(local_menu(\"programming_fundamentals\"));")); main.append(addParagraph("This is because the local menu will change depending on which course you are viewing so the parameter is the name of the course, it’s actually the same name as the folder containing the course which is useful since I am using old-fashioned routing where the URL for a particular page includes the path to it on the drive. When it is passed to the local_menu() function it us used to generate the arrays that hold the text descriptions for the links as well as the URL which includes that parameter.")); main.append(addParagraph("You can also see in the image above, the names of some of the other functions I used to generate the page content and a group of import statements which are used to call in every function I use.")); main.append(addParagraph("This is a very simple example and probably not the best way to import a group of functions but I don’t know of an easy way to do that to import JavaScript into another JavaScript file!")); main.append(addParagraph("However, in most programming languages, including python, it is possible to import a group of functions into your own code and the code is usually referred to as a module or library.")); main.append(addParagraph("In python, you would typically import code in the form of a module. For example, if we have a module called testmodule.py, we can import in into our python applications with a command such as")); main.append(addSyntax("import testmodule")); main.append(addParagraph("Note that we don’t specify the py extension and we haven’t told python where this module is located so you would use this syntax where the module is located in the same directory as your application.")); main.append(addParagraph("The test module contains a method or function called mult and if we want to call that function, we would call it in more or less the same way as we would if the module was defined in the file rather than imported. However, we have to tell python where the function is by prefacing the call with the module name. A call would therefore look something like this:")); main.append(addSyntax("testmodule.mult(10,5)")); main.append(addParagraph("Of course, the code you import doesn’t have to be code you have written yourself. The python library has plenty of modules available on line and you can, for example, download some of these from the python Package Index and you can get more information on modules from the python Documentation.")); main.append(addHeader("Understanding Libraries and Frameworks")); main.append(addParagraph("Modules are a very simple way of adding code from an external source into your own project in python, but there are others. Generally, a library is similar to a module but it tends to incorporate more code and be more general purpose. The use of libraries is common in most modern programming languages so you have the standard libraries in C, jQuery in JavaScript and in python, there are libraries for machine learning such as TensorFlow and Pandas and for Mathematical functions such as NumPy and SciPy.")); main.append(addParagraph("It’s probably fair to say that these libraries are largely responsible for the popularity of python today because they allow the language (which is generally considered to be an easy programming language to learn) to be used for things like machine learning without the user needing to know too much about programming. They make it more accessible!")); main.append(addParagraph("Framework are, in a sense, an extension of libraries because they don’t just provide you with code you can use in your own project, they also provide what is essentially a skeleton structure for the project.")); main.append(addParagraph("These may be more well-known in JavaScript with React, Angular and Vue being the most notable. There are others, for example lambdatest.com has an article entitled 27 Best JavaScript Frameworks for 2024 which may be interesting if you want to try out one or more of these.")); main.append(addParagraph("The best known frameworks for python are probably Django and Flask and you can also see an article on BrowserStack listing the Top 10 Python Web Development Frameworks in 2024.")); main.append(addParagraph("For a beginner, frameworks in particular and to some extent libraires as well are going to be much more than you need and you will probably find that your first few projects are coded largely from scratch. This site, for example, does (as of 26 October 2024)incorporate code from the jQuery library which I use to create my own functions to generate the page content but I haven’t really gotten into frameworks in a big way yet.")); main.append(addParagraph("Frameworks are more suited to large projects so you might well find that toy learn about them if you want to find a job as a web or python developer but you may not do that if you are just coding as a hobby to create your own small projects.")); main.append(addHeader("Combining and Manipulating Stings")); main.append(addParagraph("Most programming languages offer some tools for working with strings such as string concatenation and in most cases, this uses the plus sign as a concatenation operator. For example, the command")); main.append(addSyntax("print(\"computer\" + \" programming\")")); main.append(addParagraph("will concatenate the two strings and then output them as if they were a single string. Note that concatenation just joins the two strings, it doesn’t do anything else ")); main.append(addParagraph("In python, this can cause confusion. Let’s say you want to have a user input a number which you will then multiply by 10. As you may know, multiplication is really just repeated addition so 4 multiplied by 5 is equivalent to 4 + 4 + 4 + 4 + 4, to give an example.")); main.append(addParagraph("Now, consider the following snippet of code.")); main.append(addSyntax("num = input(\"Enter a number: \"")); main.append(addParagraph("If we execute this statement, which will create a variable called num and set it’s value to 27. We can then output this with a command like")); main.append(addSyntax("print(num)")); main.append(addParagraph("and the output we will get is 27. If we replace the print statement with")); main.append(addSyntax("print(num * 10)")); main.append(addParagraph("what would you expect the output to be. It looks like you are trying to produce the output 270, but what you actually get is")); main.append(addSyntax("27272727272727272727")); main.append(addParagraph("This is because the input function returns a string and so we are not performing a repeated addition, it’s actually a repeated concatenation and so we are just getting the string output 10 times in a row with no spaces")); main.append(addParagraph("We can resolve this by casting the string as an integer value with int. We can do that in a couple of ways. One way would be to create a new value and assign it the result of casting the returned value as an int, so:")); main.append(addSyntax("num_as_int = int(num)")); main.append(addParagraph("and we can then use that new variable to perform our arithmetic operation on. Another approach would be to call the input function from within the cast so that the value that is returned is cast as an int before we assign its value to num.")); main.append(addSyntax("num = int(input = \"Enter a number: \"))")); main.append(addParagraph("The main thing to take from this is that some functions and operations will work differently or may not work at all if depending on the type of a variable. There may be instances where you will have to convert one data type to another in order to perform a specific operation.")); main.append(addParagraph("Most programming languages will also provide some other functions for string manipulation. In python, for example, this includes")); main.append(addSubHeader("capitalize()")); main.append(addParagraph("This will convert a string by setting the first character to an upper case letter so if you have a name in all lower case, this will correct the string. For example, if name holds the string value \”phililp\”")); main.append(addSyntax("cap_name = name.capitalize()")); main.append(addParagraph("will set the value of cap_name to \”Philip\”")); main.append(addParagraph("For the next couple of examples, we will assume that we have a variable called note with a value of \”award: Nobel Peace Prize\”")); main.append(addSubHeader("find()")); main.append(addParagraph("This allows us to search a string to look for a specific character or sequence of characters. For example, we might want to check if the note variable contains the characters \”award: \” and we can do that with")); main.append(addSyntax("award_location = note.find(\”award: \”)")); main.append(addParagraph("This will check note for the string we are looking for, \”award: \” and will return the index value for the first character in the search string if the whole search string is found. Note that if \”award: \” is found more than once in note (which it is not, of course), this would only find the first instance. In our example, this means that 0 will be returned.")); main.append(addParagraph("In python, there is also an index() function which performs a similar function in a list or array and it will return the index value of the first instance of the argument you pass to index if that is an element of the array. Note that here we are searching for an element rather than a substring so we are not looking for a string that appears somewhere in one of the elements, we are looking for an exact match with an element,")); main.append(addParagraph("There are also similar methods which will find the last instance of something in either a string or an array and these are rfind() for searching in a string and rindex() for searching in an array.")); main.append(addParagraph("As you might expect, the data that we are really interested in in the note variable is the name of the award. Using the find method is a way of checking that its value starts with the word award followed by a colon and a space which makes it likely that what follows is the name of an award.")); main.append(addParagraph("Essentially, we want to be able to grab part of that string value, but only the part that includes the award name. We can do that using something called slice notation in python and is a form of array notation. Remember that an element of an array would be accessed with something like")); main.append(addSyntax("my_array[6]")); main.append(addParagraph("A string is really just an array of characters so we can get a part of the string by specifying it’s starting and finishing index values. For example, in this case we know that we want everything after the 7 characters that make up \”award: \” (including the colon and space) and that means our starting index value would be 7 since that is the value of the 8th character in note.")); main.append(addParagraph("Let’s say we want to create an award with only the name of the award, we can do it with:")); main.append(addSyntax("award = note[7:]")); main.append(addParagraph("You will notice that I have omitted the end index value and as a result, end is assumed to be the end of the string so we will get the character with index value 7 and everything after it.)")); main.append(addParagraph("We can similarly omit the start value and just specify the end value which would return everything up, but not including, the character with the index value specified for end so")); main.append(addSyntax("award = note[7:]")); main.append(addParagraph("will return the first 7 characters.")); main.append(addHeader("Creating Regular Expressions")); main.append(addParagraph("When you use a method like find() or index(), you don’t have to specify the exact string, you can also use a regular expression. These are commonly used in a number of programming languages, most notably Perl and AWK as well as in a Linux or Mac shell. We will look, very briefly, at how this works in python.")); main.append(addParagraph("I have covered regular expressions in other courses and LI Learning has at least one course dedicated to the subject. If you have some experience with regular expressions in other environments, bear in mind that these can be similar but not exactly the same in python.")); main.append(addParagraph("To start with, we have three variables with string values as follows:")); main.append(addInsetBulletList(["five_digit_zip = '98101'", "nine_digit_zip = '98101-0003'", "phone_number = '234-567-8901'"])); main.append(addParagraph("We want to find out if any of these strings have 5 consecutive digits which would suggest that it might contain a zip code. To start with, we have to import the module for working with regular expressions in python which is re.")); main.append(addParagraph("We will create a variable called five_digit_expression and set its value to the regex we want like this.")); main.append(addSyntax("five_digit_expression = r’\d{5}’")); main.append(addParagraph("The r indicates that the string that follows may backslashes that should be ignored by the compiler. In this example, we do have a backslash followed by a lower case d and this represents any digit (or any single digit number) and the 5 in curly braces indicates that we are looking for 5 occurrences of that expression so in this case 5 numeric digits. In other words, we are looking for a five digit number.")); main.append(addParagraph("The re module has a method for searching for a regex in a string and it is called search and it takes two arguments, the regex and the string we want to check. So we could check our first string with something like:")); main.append(addSyntax("re.search(five_digit_expression, five_digit_zip)")); main.append(addParagraph("This will perform the test for us but notice that we are not doing anything with it. There are several options we could choose ibn order to make use of the result such as store it in a variable or a list or use it in a conditional statement to run some code depending on whether or not there is a match.. In this case, we will pass this whole statement to a print statement to simply output the result.")); main.append(addSyntax("print(re.search(five_digit_expression, five_digit_zip))")); main.append(addParagraph("The result that we get output is the location of the string and the actual string that matches the regular expression so in this case:")); main.append(addSyntax("")); main.append(addParagraph("Alternatively, if there is no match, we just get None returned. The code for running all three tests as well as the output is shown below.")); main.append(addParagraph("Regular expressions can be very simple but they can also be very complex. Of course, they don’t only match with numbers, you can write regular expressions that will look for specific character strings as well as patterns of numbers as we saw here.")); main.append(addParagraph("It may actually be helpful to think of the expression you are writing as a pattern or template which can include literal elements (words, letters or special characters) and from there you can work out what your pattern should look like.")); main.append(addParagraph("For example, let’s say that you want a pattern to match with a UK postcode. For simplicity, I will assume that all postcodes follow a specific format so we have")); main.append(addInsetCodeListing(["1 or 2 letters","1 or 2 digits", "1 digit", "2 letters"])); main.append(addParagraph("The regular expression might look something like this.")); main.append(addSyntax("[A-Za-z][A-Za-z]*\d\d* \d[A-Za-z][A-Za-z]")); main.append(addParagraph("So this is 1 letter, 0 or more letters, 1 digit, 0 or more digits, a space, 1 digit, 1 letter and finally 1 letter. This would in fact match any postcode but it is not completely correct because of the 2 and 4th parts which are , 0 or more letters and 0 or more digits. This should really be 0 or 1 and because it’s not, this will also match with strings with too many characters. For example")); main.append(addSyntax("EHEH23131 5AZ")); main.append(addParagraph("Clearly this is not a valid postcode. I’m not really too concerned with fixing this because it servers a couple of purposes as is. Firstly, it demonstrates a little more on how you would write the regular expression. Secondly, since it would match any valid postcode, you might think it must be correct, but in fact it will also match with some non-valid \”postcodes\” and that in itself tells us that when we test a regular expression, it’s not enough to make sure that it matches the strings that it should, we also need to make sure it doesn’t match strings when it shouldn’t and that is just as important.")); main.append(addParagraph("For more information on regular expressions in python, there are plenty of useful resources online and these include Regular Expressions: Regexes in Python (Part 1) from realpython.com (thanks to John Sturtz for the article which is very informative) or the python documentation. Another link which you will find useful for testing any type of regular expressions, including those for python is regex101 which allows you to type in a regular expression and a string to see if the regex correctly matches a string when it should as well as when it shouldn’t.")); main.append(addHeader("Strings Challenge")); main.append(addParagraph("This was a very simple challenge and I have neglected to document the previous challenges but in this case, my solution is different to Sasha’s so I though it might be interesting to show both of them together because I think this highlights a couple of interesting points about how different approaches can produce the same results.")); main.append(addParagraph("The challenge is simply to ask someone to input a number, convert that number to kilometres and then append it to a string for output.")); main.append(addParagraph("First, here is Sasha’s solution.")); main.append(addInsetCodeListing(["miles = input('Enter a distance in miles: ')", "miles_float = float(miles)", "kilometers = miles_float * 1,.609344 ", "print('That value in kilometers is’)", "print(kilometers)"])); main.append(addParagraph("And here is my solution.")); main.append(addInsetCodeListing(["miles = int(input('Enter a distance in miles: '))", " km = miles * 1.609344", "print(miles, 'is equivalent to ', km, 'kilometres’)"])); main.append(addParagraph("Pretty much everything about my solution is different, including my UK spellings!")); main.append(addParagraph("Aside from that, notice that I have converted the return value to an int before assigning it to a variable so the effect is the same as if the function had returned an int rather than a string. Also, note that I am assuming that miles is an int value but it could be a float as well and it would be easy enough to cast the return value as an float. The conversion is the same, barring the different variable names.")); main.append(addParagraph("Note that at least one of the values has to be a string literal and we also have a float for the output so we can't use string concatenation. My way around this was to pass three arguments to the print function so it just prints them all out in the same order and Sasha has taken a slightly different approach where he outputs a string with one print statement and his float with another.")); main.append(addParagraph("The point, really, is that differences like this can be purely cosmetic such as whether or not we use a cast on the returned value before assigning it or have a string value returned and then create another variable to hold the corresponding float value.")); main.append(addParagraph("Some differences such as whether the value in miles has to be an int or whether float values are allowed.")); main.append(addParagraph("The former are usually invisible to the client since they are just different ways to achieve the same result but the latter are certainly going to be visible to the client and which is correct will normally depend on what the client has asked for so that may be an error in reading the program requirements and is therefore probably more of a critical error – certainly it has more potential to be critical!!")); main.append(addHeader("Object-Oriented Programming")); main.append(addParagraph("The fundamental principle of objects is that they allow you to reuse code. For example, let’s say that you create a call called ToDo which is used to create to do lists for different purposes such as a hone to-do list, a work to-do list, a study to-do list and so on. There are a couple of approaches you can take to doing this.")); main.append(addParagraph("The first is to create the ToDo list and within that class, define all of the methods and properties that a ToDo list needs. The important point here is methods. For example, you might have getter and setter methods to work with the properties, set the due_date, priority and so on. This is the best approach when you want to implement a series of objects that all do things in the same way but where the properties are going to be different or at least you want to be clear that a list is of the home type, work type and so on.")); main.append(addParagraph("You wouldn’t necessarily have to create sub-classes but this can be useful if you need to add methods that are specific to a particular to-do list type such as a billable() method for a work list.")); main.append(addParagraph("In that case, you are going to create a subclass called something like WorkToDo that inherits all of the methods of ToDo and then adds the methods that are only required for this category of list.")); main.append(addParagraph("With this approach, it is very possible that you will never create an instance of ToDo, but it nevertheless serves a useful purpose of allowing you to code methods that are used in its sub-classes.")); main.append(addParagraph("Another approach would be to create ToDo as an interface which means that it will specify the methods that the class needs but will not implement them. If you then create a sub-class of ToDo, the subclass would have to implement the methods in ToDo and can also add its own methods if it needs to. You cannot create instances of an interface class, only of a sub-class that implements all of the required methods.")); main.append(addParagraph("If you think about this approach in the context of the ToDo example, it seems pointless and that is perfectly reasonable. Why would you implement the same method with the same method definition in each of the sub-classes and that is something you definitely shouldn’t do. An interface class, however, can be very useful when all of the methods have to be defined in each sub-class.")); main.append(addParagraph("To further illustrate this, let’s imagine that the method for setting a due date is different for a work to-do list. For instance, you might want to implement some logic to prevent the due date being set to a Saturday or Sunday. In that case, you would implement the method in the WorkToDo class. If this method is defined in ToDo, it would be overridden by the new method but the ToDo definition would still be usable for any other sub-class.")); main.append(addParagraph("If you have a class where each subclass provides a different definition for every method, you then don’t really have any benefit in defining methods in ToDo so that’s an example where an interface would make sense.")); main.append(addParagraph("That might raise the question, why would you bother with an interface class if you are going to effectively define each of the other classes as a complete class in its own right and there are two benefits. Firstly, it can define the properties that the sub-classes need so for instance, it might have a name property and every sub-class will also have that same name property.")); main.append(addParagraph("Secondly, since it defines what methods the sub-classes will need without providing method definitions, it forces a sub-class to implement those methods. You could sum this up by saying that if you know what the structure is for the interface class, you know what the structure is of any sub-class and you know what methods it will have, excluding any that are added by the sub-class")); main.append(addParagraph("An interface may be useful when you want to create a number of classes where each class needs to be able to respond to a specific set of methods, but doesn’t need to respond in the same way as the other classes.")); addSidebar("programming");