{"id":40,"date":"2014-11-01T09:00:46","date_gmt":"2014-11-01T13:00:46","guid":{"rendered":"http:\/\/pfsensesetup.com\/pythonscript.net\/?p=40"},"modified":"2014-11-02T11:33:52","modified_gmt":"2014-11-02T16:33:52","slug":"python-modules-introduction-recursion","status":"publish","type":"post","link":"http:\/\/pfsensesetup.com\/pythonscript.net\/python-modules-introduction-recursion\/","title":{"rendered":"Python Modules; Introduction to Recursion"},"content":{"rendered":"<p><span style=\"color: #000000;\"><a href=\"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-content\/uploads\/2014\/10\/Python_logo_by_BlueX_pl.png\">\u00a0 <img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-26\" src=\"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-content\/uploads\/2014\/10\/Python_logo_by_BlueX_pl-300x300.png\" alt=\"Python module\" width=\"300\" height=\"300\" srcset=\"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-content\/uploads\/2014\/10\/Python_logo_by_BlueX_pl-300x300.png 300w, http:\/\/pfsensesetup.com\/pythonscript.net\/wp-content\/uploads\/2014\/10\/Python_logo_by_BlueX_pl-150x150.png 150w, http:\/\/pfsensesetup.com\/pythonscript.net\/wp-content\/uploads\/2014\/10\/Python_logo_by_BlueX_pl.png 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>If you quit the Python interpreter and enter it again without saving your program to a text file, the definitions you have made will be lost. Therefore, if you want to write a somewhat longer program, you are better off using a text editor to prepare the input for the interpreter and running it with that file as input instead. In doing so, we create scripts. As your program gets longer, you may also want to split it into several files for easier maintenance.<\/span><\/p>\n<h3><span style=\"text-decoration: underline;\"><strong>Python Modules<\/strong><\/span><\/h3>\n<p><span style=\"color: #000000;\">To support this, Python provides a way of putting definitions into a file and using them in a script or in an interactive instance of the interpreter. Such a file is called a module; definitions from a Python module can be imported into other modules or into the main Python modules.<\/span><\/p>\n<p><span style=\"color: #000000;\">A Python module is a file containing Python definitions and statements; such a file always ends with the suffix .py. Up to this point, we have not introduced Python definitions. A definition in Python always starts with def and is followed by its name. This is the equivalent of a function in C or Pascal. For example:<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>def hello():<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0 \u00a0 \u00a0 print(&#8216;Hello, world!&#8217;)<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">is a very simple Python function to print out &#8220;Hello, world!&#8221;. If this code is saved in a file called <strong>hello.py<\/strong>, and is in Python&#8217;s path, you can import it at the Python command line:<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>&gt;&gt;&gt; import hello<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">Once the Python module is imported, you can invoke the hello function with:<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>&gt;&gt;&gt; hello.hello()<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">As with C and other languages, you can specify parameters. For example:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><strong>def isZero(a):<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0if a == 0:<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0 \u00a0 print('a is zero')<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0else:\r\n       print('a is a non-zero number')<\/strong><\/span>\r\n\r\n<\/pre>\n<p><span style=\"color: #000000;\">You can also return a value from the function:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><strong>def isZero(a):<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0 if a == 0:<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0 \u00a0 \u00a0return True<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0 else:<\/strong><\/span>\r\n<span style=\"color: #000000;\"> <strong>\u00a0 \u00a0    return False<\/strong><\/span>\r\n<\/pre>\n<p><span style=\"color: #000000;\">As in other languages such as C\/C++, we can specify default parameters. For example:<\/span><\/p>\n<p><span style=\"color: #000000;\">def isZero(a=0):<\/span><\/p>\n<p><span style=\"color: #000000;\">allows us to invoke the function isZero with no arguments; the interpreter will insert a value of 0 for a if no arguments are specified. However, a non-default argument cannot follow a default argument. Thus:<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>def isZero(a=0,b):<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">is not allowed, but:<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>def isZero(a,b=0):<\/strong><\/span><\/p>\n<p><span style=\"color: #000000;\">is allowed.<\/span><\/p>\n<p><span style=\"color: #000000;\">This is a decent start, but it would be nice if we came up with a program that can do something useful.<\/span><\/p>\n<h3><span style=\"text-decoration: underline;\"><strong>Introduction to Recursion<\/strong><\/span><\/h3>\n<p><span style=\"color: #000000;\">In computer science, recursion is a method where the solution to a problem depends on solutions to smaller instances of the same problem. Recursion always involves the existence of one more more base cases in which an operation can be done directly on the input data. The other cases involve invoking the same function on a subset of the input data in a divide-and-conquer strategy. The approach can be applied to many types of problems &#8211; for example, finding palindromes. It shouldn&#8217;t be too difficult to come up with a Python module to solve this problem.<\/span><\/p>\n<p><span style=\"color: #000000;\">A palindrome is a word, phrase, number, or other sequence of symbols or elements that read the same forward or reversed: for example, &#8220;Race car&#8221;, or &#8220;A man, a plan, a canal &#8211; Panama&#8221;. A solution of the problem for finding a palindrome using recursion can be outlined as follows:<\/span><\/p>\n<ol>\n<li><span style=\"color: #000000;\">If the input string length is 0 or 1, then we have a palindrome &#8211; return true<\/span><\/li>\n<li><span style=\"color: #000000;\">If the input string length is greater than 1 but the first and last character match, apply the test recursively to the string minus the first and last characters<\/span><\/li>\n<li><span style=\"color: #000000;\">If [1] and [2] don&#8217;t apply, then we don&#8217;t have a palindrome &#8211; return false<\/span><\/li>\n<\/ol>\n<p><span style=\"color: #000000;\">Successive applications of this process on the input string will eventually yield either a mismatch between the first and last character or an input string of length 0 or 1, and the test will be complete. We can code this algorithm in Python as follows:<\/span><\/p>\n<pre><span style=\"color: #0000ff;\"><strong>def isPalindrome(myString):<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0''' Simple program to find palindromes, part of our Python module<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> Parameters: myString =&gt; string to perform test on<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> If length &lt;= 1, it's a palindrome - return True<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> If first char is the same as the last char, apply algorithm recursively<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0Otherwise return False <\/strong><strong>'''<\/strong><\/span>\r\n<span style=\"color: #0000ff;\">  <strong>if len(myString) &lt;= 1:<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0 \u00a0 return True<\/strong><\/span>\r\n<span style=\"color: #0000ff;\">  <strong> elif myString[0].lower() == myString[len(myString)-1].lower():<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0 \u00a0 return isPalindrome(myString[1:(len(myString)-1)])<\/strong><\/span>\r\n<span style=\"color: #0000ff;\">  <strong>return False<\/strong><\/span>\r\n \r\n<\/pre>\n<p><span style=\"color: #000000;\">Our isPalindrome function takes in a single argument, myString. We introduced two hitherto unseen functions here. len() takes a single parameter &#8211; a string &#8211; and returns the length. lower() is a member of the string class and converts the string into lowercase. This ensures that our test is not case-sensitive. You may have noticed that there is one shortcoming of this algorithm: if there are spaces or any other alphanumeric content in the string, it will return false. I decided it would be easier to write a separate function to strip the non-alphanumeric characters out:<\/span><\/p>\n<pre><span style=\"color: #0000ff;\"> <strong>def convertToAlphaNum(myString):<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0''' Iterate through the string and generate an output string with only the alphanumeric chars (also part of the palindrome.py Python module)<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> Parameters: myString =&gt; the string to convert<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> Returns: A copy of the string with all non-alphanumeric<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0characters removed '''<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> retval = ''<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> for c in myString:<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0 \u00a0 \u00a0if c.isalpha() or c.isdigit():<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0retval += c<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"> <strong> return retval<\/strong><\/span>\r\n<\/pre>\n<p><span style=\"color: #000000;\">All this function does is iterate through the input string and if a character is a letter or digit, it gets added to a new string. When it is done, the function returns the new string. We still need a function to read input from the user and call these functions, so that will be our next bit of code, and the last function in our Python module:<\/span><\/p>\n<pre><span style=\"color: #0000ff;\"><strong>def testPalindrome():<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong>\u00a0''' Part of the palindrome. py Python module - <\/strong><\/span><span style=\"color: #0000ff;\"><strong>Prompt user for string input<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong> Output whether it is a palindrome or not '''<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong> myString = str(input('Enter a string: '))<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong> if isPalindrome(convertToAlphaNum(myString)):<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong>\u00a0 \u00a0 print(myString,'is a palindrome')<\/strong><\/span>\r\n<span style=\"color: #0000ff;\"><strong> else:<\/strong><\/span>\r\n<span style=\"color: #000000;\"><strong>\u00a0 \u00a0<span style=\"color: #0000ff;\"> print(myString,'is not a palindrome')<\/span><\/strong><\/span>\r\n<\/pre>\n<p><span style=\"color: #000000;\">This function simply prompts the user to input a string and uses the previous functions to determine whether or not it is a palindrome, and prints the results.<\/span><\/p>\n<p><span style=\"color: #000000;\">Once these functions are saved to a file, you can load the file into IDLE using the <strong>File<\/strong> -&gt; <strong>Open<\/strong> menu option (or CTRL-O). The Python module will load into a separate window; from that window, select <strong>Run<\/strong> -&gt; <strong>Run Module<\/strong> (or press F5). Then from the main IDLE window, you can run testPalindrome():<\/span><\/p>\n<p><span style=\"color: #000000;\"><strong>&gt;&gt;&gt; testPalindrome()<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Enter a string: sample text<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> sample text is not a palindrome<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> &gt;&gt;&gt; testPalindrome()<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Enter a string: A man, a plan, a canal &#8211; Panama<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> A man, a plan, a canal &#8211; Panama is a palindrome<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> &gt;&gt;&gt; testPalindrome()<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Enter a string: No &#8216;x&#8217; in Nixon<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> No &#8216;x&#8217; in Nixon is a palindrome<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> &gt;&gt;&gt; testPalindrome()<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Enter a string: No &#8216;x&#8217; in Ford<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> No &#8216;x&#8217; in Ford is not a palindrome<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> &gt;&gt;&gt; testPalindrome()<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Enter a string: Able I was, ere saw I Elba<\/strong><\/span><br \/>\n<span style=\"color: #000000;\"><strong> Able I was, ere saw I Elba is a palindrome<\/strong><\/span><\/p>\n<p>The source code for for these functions is available as a single Python module, via <a href=\"http:\/\/pythonscript.net\/pythonscripts\/palindrome.py\">this link<\/a>.<\/p>\n<p><span style=\"color: #000000;\">It&#8217;s not the most elegant solution, but it does seem to work. In the next article, we will continue our look at programming in Python, including a second look at using recursion to solve problems.<\/span><\/p>\n<h3><span style=\"text-decoration: underline;\"><strong>External Links:<\/strong><\/span><\/h3>\n<p><a href=\"https:\/\/docs.python.org\/\">Python documentation from the official Python website<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0 If you quit the Python interpreter and enter it again without saving your program to a text file, the definitions you have made will be lost. Therefore, if you want to write a somewhat longer program, you are better off using a text editor to prepare the input for the interpreter and running it [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[25,27,24,26],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-tutorials","tag-module","tag-palindrome","tag-python-module","tag-recursion","entry"],"_links":{"self":[{"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":4,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"predecessor-version":[{"id":45,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/posts\/40\/revisions\/45"}],"wp:attachment":[{"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/pfsensesetup.com\/pythonscript.net\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}