15
Tue, Oct
6 New Articles

More Programming in Python

Programming - Other
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Python has a bunch of built-in functions, and it also comes with a whole list of modules and classes that can be used to construct your programs. I introduce programming in Python here. In most cases, you will start by building functions, and those functions may, or may not, be combined into modules at some point. We’ll take it a step at a time.

Editor's Note: This article is excerpted from chapter 9 of Open Source Starter Guide for IBM i Developers, by Pete Helgren.

Functions

For RPG programmers, at least the more “modern” ones (whoever they are), monolithic code is an anathema. It’s hard to read, hard to debug, and hard to share. And if you do decide to share or copy it, then if you tweak the “mother” of the others, you need to update the others as well. Most RPG and COBOL programmers I know abandoned that technique about the time that Prince changed his name to ... well, whatever it was changed to. What replaced the monolithic coding style? Well, subroutines were the first step, and then subprocedures, and then those were gathered into service programs, which made for nice, neat bundles of goodness in the ILE world. Leveraging those service programs across multiple applications made for nice, easy-to-maintain code. I am not going to make you relive that process; we’ll just start at the service program equivalent: functions with modules.

Modules are just groups of functions gathered into a source file that can be included in other source files. There isn’t much magic to modules; you just need to “import” them when you need the functions within them, kind of like using a BNDDIR in your H-specs to reference a procedure in a service module.

Functions come in all shapes and sizes. Functions begin with a def and finish with a return (in most cases). Between the def and return would be 1) a function name followed by parentheses, 2) input parameters to go within the parentheses if needed, 3) a colon (:), 4) an optional string that describes what the function is (docstring), 5) a block of code, and 6) a return statement that could return a value to the caller or can just be left blank.

A prototype would be like this:

More Programming in Python - Figure 1

Let’s continue the example by going back to some of the code above and “functionalizing” it. Remember that we tiptoed through the tuples like so:

More Programming in Python - Figure 2

We can create a function that would handle just that bit of code:

More Programming in Python - Figure 3

The output is just the same as before:

More Programming in Python - Figure 4

I need to mention something that is unique to Python, and that is indentation matters. This will probably come back to you time and time again, since I often get it wrong myself. It doesn’t matter if you indent using tabs or spaces; just be consistent and make sure your indentations are properly relative to each other. This is where a good text editor that can syntax-check your Python will be very helpful.

Modules

If you took the function and stuffed it inside a file called myMod.py, you could then use that function by issuing the following:

More Programming in Python - Figure 5

You’d get the same output with the added advantage that you can use the tttt function in other programs with just one line of code: import myMod.

That is about all the complexity that a module has: it is a file containing one or more functions, and usually those functions are in the module because the functionality they bring to the party is broad-based. Outside of easing maintenance by locating similar functions in a single file, the utility of a module is that typically the functions they encapsulate can be used in multiple programs.

I didn’t mention scope, but since the parameters are passed by reference, you need to remember that variables declared local to the function are private to that function. For example, suppose you have a function like this:

More Programming in Python - Figure 6

Part of me expects that the phrase variable would be changed because it was changed inside the function. But I’d be disappointed. Here is what we get:

Outside the function

Inside the function

Outside the function

We get that result because the phrase variable declared inside the function is “local” to the function, even though it may be the same name as the parameter passed in.

When declared as above, the parameters are required. If we ran the same code as above but, instead of calling sayit(phrase), we forgot and called sayit(), we would see this:

More Programming in Python - Figure 7

So, if you need three parameters, then you have to have three parameters passed to it, and they all need to be in the correct order that the function expects them in.

Another possible way to pass parameters would be to use keywords when the parameters are passed to the function. Suppose you had a function like this:

More Programming in Python - Figure 8

The output is:

Name: Joe Zablotnik

Address: 123 Main Street

Name: Joe Zablotnik

Address: 123 Main Street

Remove the keywords, and you’ll get this:

Name: Joe Zablotnik

Address: 123 Main Street

Name: 123 Main Street

Address: Joe Zablotnik

If you are not sure how many parameters you’ll be passing, you can always allow any number of arguments to be passed in, like so:

More Programming in Python - Figure 9

The function doesn’t really care, but we need to at least figure out how many parms were passed in because we need to deal with them in the code. That means we evaluate how many were passed in and handle them individually. Note also that the passed parameters are tuples.

Perhaps a clearer way to handle a variable number of variables would be to use keyword variables so we know what we are looking for, and when we find it, we use it, like this:

More Programming in Python - Figure 10

So far, so good, and no convolutions like “blocks” in Ruby.

But if we stray into the realm of anonymous functions in Python, then things get a little “out there.” Anonymous functions are relatively unknown to IBM i programmers unless they are JavaScript developers, Ruby developers, or Java developers using Java 8. Basically, an anonymous function allows you to declare a function without needing a def and a return. In Python, they are known as lambda functions (JavaScript and Ruby have them as well). They sound a bit freakish, and in some respects they are, but they can be pretty useful in some situations. The best example I could assemble looks like this (and now for something completely different):

More Programming in Python - Figure 11

Let’s take it a step at a time.

In the example above, we are declaring a “regular” function (increment_it), but we return the value to a lambda, along with a parameter, and the lambda function then returns a value. increment_it as a function takes a single value and returns. But that return then passes it to a lambda function, which has one parameter that takes the return value and adds whatever was passed to it to the value passed to increment_it. So that is a killer first line. The second and third lines could appear equally cryptic, but remember that variables in Python are dynamic and can hold any object, and in this case fii and gii are lambda functions themselves that will be initialized with the increments of 2 and 6, respectively. Let me say that again: fii and gii are variables holding lambda functions with slightly different values for increment_it. The very last line shows how the whole thing is invoked, passing 22 as the increment to increment_it, and 33 will be passed to the lambda function. Here are the results:

44 48

55

Pretty nice. Lambda become helpful in just these kinds of situations where an output from a named function needs to be further processed without the overhead of writing a traditional function. You probably won’t be writing a lambda right out of the blocks, but you are bound to run into them at some point. Might as well familiarize you with them now rather than have you run out of the room screaming hysterically later.

Classes in Python

Before we move on to a more complete code example, we have to embrace the object- oriented nature of Python by reviewing classes. As mentioned in other chapters of this book, a class is really a template of how an object should look and act. It defines the object’s properties, data, and functions and provides a method for initializing and creating objects based on the class.

A simple example is this:

More Programming in Python - Figure 12

This is simple and contrived, but it demonstrates a few things. First, you can have an initialization routine that takes the initial value and stores it in an instance variable in the object when created. Second, you have a class variable that will be shared across all instances of the class (that is the Talker.talkerCount as opposed to using something like self.talkerCount). Third, Klingon is the universal language spoken by all Talkers.

The output would be:

nuqneH

nuqneH

Hola

Bonjour

2

If you included a module for speaking Klingon, klingon.py, you could just include the module in your Talker class so that all talkers would speak Klingon. Take a look.

Our klingon.py has this:

More Programming in Python - Figure 13

And our Talker class now looks like this:

More Programming in Python - Figure 14

Invoke the code:

More Programming in Python - Figure 15

The output:

nuqneH

nuqneH

Hola

Bonjour

2

File Access in Python

How about a simple example with a little more oomph and less mystery? File access is something you’ll probably be doing on a regular basis, and Python has no problems with file access. Let’s build a file and read through it. Here is the whole tamale:

More Programming in Python - Figure 1

Don’t ya just love it? With very little code, you can get a boatload of work done.

Most of the magic is in that first line: import csv. That module provides quite a bit of functionality, and we get all of it on that one line. The first line is a comment (the # sign denotes comments). The second line may look a little foreign to someone who hasn’t spent time in the object-oriented world, but there is real beauty in the second line. We have a variable that we are calling writer (good name, since it will be writing our data), and we assign that variable the result of a call to the writer function in the csv module. That writer takes an object returned from the open function, and the open function, which is a built-in function in Python, so it isn’t qualified by a csv, takes a filename, a mode string, which identifies how the file should be created and used, and a third optional parameter that determines how the file I/O will be buffered. Open will return a handle to the file, which the writer object will reference to write to the file. I say “write” because the string 'wb' that was passed to open means that the file will be created if it doesn’t exist; it will be open for writing, and it will contain binary data 'b'. We won’t deep dive into file I/O, but there are plenty of options and methods at your disposal.

So, out of the wonderful second line of code, we get an object called writer (we could have called it anything). That object has functions that can be used to write to the file. The function we leverage immediately is writerows. Now, we could have used writerow (singular) and written the rows one at a time, but writerows allows us to push it all in in “one swell foop.” Note that the parameter passed in is a sequence (array) of tuple objects. Yeah, you know this stuff!

Reading the file is just as easy. Again, the csv module has a reader function that returns a reader object we called inventory. The csv.reader function is passed a file object, which is returned from the built-in file open function that is passed the filename and the “mode,” which is the string 'rb', which means the file is opened read-only for binary data.

The interesting part here is the status_labels variable, which has a dictionary object in it with three name-value pairs. Jump down a couple of lines to where the variable is actually used. You’ll see that the status variable is populated by three functions rather tersely combined on the line. The cmp function compares two values and returns one of three results: It returns -1 if the left comparator is less than the right; it returns 0 if they are equal; and it returns 1 if the left comparator is greater than the right. We cast the qty parameter to an int so that the comparison is performed “apples to apples” (remember that our variables can be dynamically typed). Our comparison is to the integer 500, so our quantities in each inventory record are compared to 500 each time. The cool part is that the return value (-1, 0, or 1) is then used to retrieve a value from our status_labels dictionary—for example, status_labels[ ]. And that value is used as the value for the status variable. Nice!

 

Peter Helgren

Peter Helgren is programmer/team lead at Bible Study Fellowship International. Pete is an experienced programmer in the ILE RPG, PHP, Java, Ruby/Rails, C++, and C# languages with more than 25 years of system 3X/AS400/iSeries/IBM i experience. He holds certifications as a GIAC certified Secure Software Programmer-Java and as an MCSE. He is currently executive vice president on the COMMON Board of Directors and is active on several COMMON committees. His passion has always been in system integration, and he focuses on open-source applications and integration activities on IBM i. Pete is a speaker/trainer in RPG modernization, open-source integration, mobile application development, Java programming, and PHP and actively blogs at petesworkshop.com.


MC Press books written by Peter Helgren available now on the MC Press Bookstore.

Open Source Starter Guide for IBM i Developers Open Source Starter Guide for IBM i Developers
Check out this practical introduction to open-source development options, including XMLSERVICE, Ruby/Rails, PHP, Python, Node.js, and Apache Tomcat.
List Price $59.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: