Book Image

Python for Secret Agents

By : Steven F. Lott, Steven F. Lott
Book Image

Python for Secret Agents

By: Steven F. Lott, Steven F. Lott

Overview of this book

Table of Contents (12 chapters)
Python for Secret Agents
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Organizing our software


Python gives us a number of ways to organize software into conceptual units. Long, sprawling scripts are hard to read, repair, or extend. Python offers us packages, modules, classes, and functions. We'll see different organizing techniques throughout our agent training. We'll start with function definition.

We've used a number of Python's built-in functions in the previous sections. Defining our own function is something we do with the def statement. A function definition allows us to summarize (and in some cases generalize) some processing. Here's a simple function we can use to get a decimal value from a user:

def get_decimal(prompt):
    value= None
    while value is None:
        entry= input(prompt)
        try:
            value= Decimal(entry)
        except decimal.InvalidOperation:
            print("Invalid: ", entry)
    return value

This follows the design we showed previously, packaged as a separate function. This function will return a proper Decimal object: the value of the value variable. We can use our get_decimal() function like this:

grd_usd= get_decimal("GRD conversion: ")

Python allows a great deal of variability in how argument values are supplied to functions. One common technique is to have an optional parameter, which can be provided using a keyword argument. The print() function has this feature, we can name a file by providing a keyword argument value.

import sys
print("Error", file=sys.stderr)

If we don't provide the file parameter, the sys.stdout file is used by default.

We can do this in our own functions with the following syntax:

def report( grd_usd, target=sys.stdout ):
    lunch_grd= Decimal('12900')
    bribe_grd= 50000
    cab_usd= Decimal('23.50')

    lunch_usd= (lunch_grd/grd_usd).quantize(PENNY)
    bribe_usd= (bribe_grd/grd_usd).quantize(PENNY)

    receipt_1 = "{0:12s}              {1:6.2f} USD"
    receipt_2 = "{0:12s} {1:8.0f} GRD {2:6.2f} USD"
    print( receipt_2.format("Lunch", lunch_grd, lunch_usd), file=target )
    print( receipt_2.format("Bribe", bribe_grd, bribe_usd), file=target )
    print( receipt_1.format("Cab", cab_usd), file=target )
    print( receipt_1.format("Total", lunch_usd+bribe_usd+cab_usd), file=target )

We defined our report function to have two parameters. The grd_usd parameter is required. The target parameter has a default value, so it's optional.

We're also using a global variable, PENNY. This was something we set outside the function. The value is usable inside the function.

The four print() functions provide the file parameter using the keyword syntax: file=target. If we provided a value for the target parameter, that will be used; if we did not provide a value for target, the default value of the sys.stdout file will be used. We can use this function in several ways. Here's one version:

rate= get_decimal("GRD conversion: ")
print(rate, "GRD = 1 USD")
report(rate)

We provided the grd_usd parameter value positionally: it's first. We didn't provide a value for the target parameter; the default value will be used.

Here's another version:

rate= get_decimal("GRD conversion: ")
print(rate, "GRD = 1 USD", file=sys.stdout)
report(grd_usd=rate, target=sys.stdout)

In this example, we used the keyword parameter syntax for both the grd_usd and target parameters. Yes, the target parameter value recapitulated the default value. We'll look at how to create our own files in the next section.