# Augmented Assignment

## Chapter 3: Operators, Expressions, and Program Flow¶

The focus of this chapter is an in-depth look at each of the ways that we can evaluate code, and write meaningful blocks of conditional logic. We’ll cover the details of many operators that can be used in Python expressions. This chapter will also cover some topics that have already been discussed in more meaningful detail such as the looping constructs, and some basic program flow.

We’ll begin by discussing details of expressions. If you’ll remember from Chapter 1, an expression is a piece of code that evaluates to produce a value. We have already seen some expressions in use while reading through the previous chapters. In this chapter, we’ll focus more on the internals of operators used to create expressions, and also different types of expressions that we can use. This chapter will go into further detail on how we can define blocks of code for looping and conditionals.

This chapter will also go into detail on how you write and evaluate mathematical expressions, and Boolean expressions. And last but not least, we’ll discuss how you can use augmented assignment operations to combine two or more operations into one.

## Types of Expressions¶

An expression in Python is a piece of code that produces a result or value. Most often, we think of expressions that are used to perform mathematical operations within our code. However, there are a multitude of expressions used for other purposes as well. In Chapter 2, we covered the details of String manipulation, sequence and dictionary operations, and touched upon working with sets. All of the operations performed on these objects are forms of expressions in Python. Other examples of expressions could be pieces of code that call methods or functions, and also working with lists using slicing and indexing.

## Mathematical Operations¶

The Python contains all of your basic mathematical operations. This section will briefly touch upon each operator and how it functions. You will also learn about a few built-in functions which can be used to assist in your mathematical expressions.

Assuming that this is not the first programming language you are learning, there is no doubt that you are at least somewhat familiar with performing mathematical operations within your programs. Python is no different than the rest when it comes to mathematics, as with most programming languages, performing mathematical computations and working with numeric expressions is straightforward. Table 3-1 lists the numeric operators.

*Table 3-1. Numeric Operators*

Operator | Description |

+ | Addition |

- | Subtraction |

* | Multiplication |

/ | Division |

// | Truncating Division |

% | Modulo (Remainder of Division) |

** | Power Operator |

+var | Unary Plus |

-var | Unary Minus |

Most of the operators in Table 3-1 work exactly as you would expect, so for example:

*Listing 3-1. Mathematical Operator*

However, division, truncating division, modulo, power, and the unary operators could use some explanation. Truncating division will automatically truncate a division result into an integer by rounding down, and modulo will return the remainder of a truncated division operation. The power operator does just what you’d expect as it returns the result of the number to the left of the operator multiplied by itself n times, where n represents the number to the right of the operator.

*Listing 3-2. Truncating Division and Powers*

Division itself is an interesting subject as its current implementation is somewhat controversial in some situations. The problem 10/5 = 2 definitely holds true. However, in its current implementation, division rounds numbers in such a way that sometimes yields unexpected results. There is a new means of division available in Jython 2.5 by importing from __future__. In a standard division for 2.5 and previous releases, the quotient returned is the floor (nearest integer after rounding down) of the quotient when arguments are ints or longs. However, a reasonable approximation of the division is returned if the arguments are floats or complex. Often times this solution is not what was expected as the quotient should be the reasonable approximation or “true division” in any case. When we import division from the __future__ module then we alter the return value of division by causing true division when using the / operator, and floor division only when using the , // operator. In an effort to not break backward compatibility, the developers have placed the repaired division implementation in a module known as __future__. The __future__ module actually contains code that is meant to be included as a part of the standard language in some future revision. In order to use the new repaired version of division, it is important that you always import from __future__ prior to working with division. Take a look at the following piece of code.

*Listing 3-3. Division Rounding Issues*

As you can see, when we’d expect to see a decimal value we are actually receiving an integer value. The developers of this original division implementation have acknowledged this issue and repaired it using the new __future__ implementation.

*Listing 3-4. Working With __future__ Division*

It is important to note that the Jython implementation differs somewhat from CPython in that Java provides extra rounding in some cases. The differences are in display of the rounding only as both Jython and CPython use the same IEEE float for storage. Let’s take a look at one such case.

*Listing 3-5. Subtle Differences Between Jython and CPython Division*

Unary operators can be used to evaluate positive or negative numbers. The unary plus operator multiplies a number by positive 1 (which generally doesn’t change it at all), and a unary minus operator multiplies a number by negative 1.

*Listing 3-6. Unary Operators*

As stated at the beginning of the section, there are a number of built-in mathematical functions that are at your disposal. Table 3-2 lists the built-in mathematical functions.

*Table 3-2. Mathematical Built-in Functions*

Function | Description |

abs(var) | Absolute value |

pow(x, y) | Can be used in place of ** operator |

pow(x,y,modulo) | Ternary power-modulo (x **y) % modulo |

round(var[, n]) | Returns a value rounded to the nearest 10-n or (10**-n), where n defaults to 0) |

divmod(x, y) | Returns a tuple of the quotient and the remainder of division |

*Listing 3-7. Mathematical Built-ins*

## Comparison Operators¶

Comparison operators can be used for comparison of two or more expressions or variables. As with the mathematical operators described above, these operators have no significant difference to that of Java. See Table 3-3.

*Table 3-3. Comparison Operators*

Operator | Description |

> | Greater than |

< | Less than |

>= | Greater than or equal |

<= | Less than or equal |

!= | Not equal |

== | Equal |

*Listing 3-8. Examples of Comparison Operators*

## Bitwise Operators¶

Bitwise operators in Python are a set of operators that are used to work on numbers in a two’s complement binary fashion. That is, when working with bitwise operators numbers are treated as a string of bits consisting of 0s and 1s. If you are unfamiliar with the concept of two’s complement, a good place to start would be at the Wikipedia page discussing the topic: (http://en.wikipedia.org/wiki/Two’s_complement). It is important to know that bitwise operators can only be applied to integers and long integers. Let’s take a look at the different bitwise operators that are available to us (Table 3-4), and then we’ll go through a few examples.

*Table 3-4. Bitwise Operators*

Operator | Description |

& | Bitwise and operator copies a bit to the result if a bit appears in both operands |

|| | Bitwise or operator copies a bit to the result if it exists in either of the operands |

^ | Bitwise xor operator copies a bit to the result if it exists in only one operand |

~ | Bitwise negation operator flips the bits, and returns the exact opposite of each bit |

Suppose we have a couple of numbers in binary format and we would like to work with them using the bitwise operators. Let’s work with the numbers 14 and 27. The binary (two’s complement) representation of the number 14 is 00001110, and for 27 it is 00011011. The bitwise operators look at each 1 and 0 in the binary format of the number and perform their respective operations, and then return a result. Python does not return the bits, but rather the integer value of the resulting bits. In the following examples, we take the numbers 14 and 27 and work with them using the bitwise operators.

*Listing 3-9. Bitwise Operator Examples*

To summarize the examples above, let’s work through the operations using the binary representations for each of the numbers.

The shift operators (see Table 3-5) are similar in that they work with the binary bit representation of a number. The left shift operator moves the left operand’s value to the left by the number of bits specified by the right operand. The right shift operator does the exact opposite as it shifts the left operand’s value to the right by the number of bits specified by the right operand. Essentially this translates to the left shift operator multiplying the operand on the left by the number two as many times as specified by the right operand. The opposite holds true for the right shift operator that divides the operand on the left by the number two as many times as specified by the right operand.

*Table 3-5. Shift Operators*

x<<n | Shift left (The equivalent of multiplying the number x by 2, n times) |

x>>n | Shift right (The equivalent of dividing the number x by 2, n times) |

More specifically, the left shift operator (<<) will multiply a number by two n times, n being the number that is to the right of the shift operator. The right shift operator will divide a number by two n times, n being the number to the right of the shift operator. The __future__division import does not make a difference in the outcome of such operations.

*Listing 3-10. Shift Operator Examples*

While bitwise operators are not the most commonly used operators, they are good to have on hand. They are especially important if you are working in mathematical situations.

## Augmented Assignment¶

Augmented assignment operators (see Table 3-6) combine an operation with an assignment. They can be used to do things like assign a variable to the value it previously held, modified in some way. While augmented assignment can assist in coding concisely, some say that too many such operators can make code more difficult to read.

*Listing 3-11. Augmented Assignment Code Examples*

*Table 3-6. Augmented Assignment Operators*

Operator | Equivalent |

a += b | a = a + b |

a -= b | a = a – b |

a *= b | a = a * b |

a /= b | a = a / b |

a %= b | a = a % b |

a //= b | a = a // b |

a **= b | a = a** b |

a &= b | a = a & b |

a |= b | a = a | b |

a ^= b | a = a ^ b |

a >>= b | a = a >> b |

a <<= b | a = a << b |

## Boolean Expressions¶

Evaluating two or more values or expressions also uses a similar syntax to that of other languages, and the logic is quite the same. Note that in Python, True and False are very similar to constants in the Java language. True actually represents the number 1, and False represents the number 0. One could just as easily code using 0 and 1 to represent the Boolean values, but for readability and maintenance the True and False “constants” are preferred. Java developers, make sure that you capitalize the first letter of these two words as you will receive an ugly NameError if you do not.

Boolean properties are not limited to working with int and bool values, but they also work with other values and objects. For instance, simply passing any non-empty object into a Boolean expression will evaluate to True in a Boolean context. This is a good way to determine whether a string contains anything. See Table 3-7.

*Listing 3-12. Testing a String*

*Table 3-7. Boolean Conditionals*

Conditional | Logic |

and | In an x and y evaluation, if x evaluates to false then its value is returned, otherwise y is evaluated and the resulting value is returned |

or | In an x or y evaluation, if x evaluates to true then its value is returned, otherwise y is evaluated and the resulting value is returned |

not | In a not x evaluation, if not x, we mean the opposite of x |

As with all programming languages, there is an order of operations for deciding what operators are evaluated first. For instance, if we have an expression a + b *c, then which operation would take place first? The order of operations for Python is shown in Table 3-8 with those operators that receive the highest precedence shown first, and those with the lowest shown last. Repeats of the same operator are grouped from left to the right with the exception of the power (**) operator.

*Table 3-8. Python Order of Operations*

Operator Precedence from Highest to Lowest | Name |

+var, -var, ~var | Unary Operations |

** | Power Operations |

*, /, //, % | Multiplication, Division, Floor Division, Modulo |

+, - | Addition, Subtraction |

<<, >> | Left and Right Shift |

& | Bitwise And |

^ | Bitwise Exclusive Or |

|| | Bitwise Or |

<, >, <=. >= , <> | Comparison Operators |

==, != , is, is not, in, not in | Equality and Membership |

and, or, not | Boolean Conditionals |

An important note is that when working with Boolean conditionals, ‘and’ and ‘or’ group from the left to the right. Let’s take a look at a few examples.

*Listing 3-13. Order of Operations Examples*

## Conversions¶

There are a number of conversion functions built into the language in order to help conversion of one data type to another (see Table 3-9). While every data type in Jython is actually a class object, these conversion functions will really convert one class type into another. For the most part, the built-in conversion functions are easy to remember because they are primarily named after the type to which you are trying to convert.

*Table 3-9. Conversion Functions*

Function | Description |

chr(value) | Converts integer to a character |

complex(real [,imag]) | Produces a complex number |

dict(sequence) | Produces a dictionary from a given sequence of (key, value) tuples |

eval(string) | Evaluates a string to return an object…useful for mathematical computations. Note: This function should be used with extreme caution as it can pose a security hazard if not used properly. |

float(value) | Converts number to float |

frozenset(set) |Converts a set into a frozen set | |

hex(value) | Converts an integer into a string representing that number in hex |

int(value [, base]) | Converts to an integer using a base if a string is given |

list(sequence) | Converts a given sequence into a list |

long(value [, base]) | Converts to a long using a base if a string is given |

oct(value) | Converts an integer to a string representing that number as an octal |

ord(value) | Converts a character into its integer value |

repr(value) | Converts object into an expression string. Same as enclosing expression in reverse quotes ( x + y). Returns a string containing a printable and evaluable representation of the object |

set(sequence) | Converts a sequence into a set |

str(value) | Converts an object into a string Returns a string containing a printable representation of the value, but not an evaluable string |

tuple(sequence) | Converts a given sequence to a tuple |

unichr(value) | Converts integer to a Unicode character |

*Listing 3-14. Conversion Function Examples*

The following is an example of using the eval() functionality as it is perhaps the one conversion function for which an example helps to understand. Again, please note that using the eval() function can be dangerous and impose a security threat if used incorrectly. If using the eval() function to accept text from a user, standard security precautions should be set into place to ensure that the string being evaluated is not going to compromise security.

*Listing 3-15. Example of eval()*

## Using Expressions to Control Program Flow¶

As you’ve learned in previous references in this book, the statements that make up programs in Python are structured with attention to spacing, order, and technique. Each section of code must be consistently spaced as to set each control structure apart from others. One of the great advantages to Python’s syntax is that the consistent spacing allows for delimiters such as the curly braces {} to go away. For instance, in Java one must use curly braces around a for loop to signify a start and an end point. Simply spacing a for loop in Python correctly takes place of the braces. Convention and good practice adhere to using four spaces of indentation per statement throughout the entire program. For more information on convention, please see PEP 8, Style Guide for Python Code (www.python.org/dev/peps/pep-0008/). Follow this convention along with some control flow and you’re sure to develop some easily maintainable software.

### if-elif-else Statement¶

The standard Python if-elif-else conditional statement is used in order to evaluate expressions and branch program logic based upon the outcome. An if-elif-else statement can consist of any expressions we’ve discussed previously. The objective is to write and compare expressions in order to evaluate to a True or False outcome. As shown in Chapter 1, the logic for an if-elif-else statement follows one path if an expression evaluates to True, or a different path if it evaluates to False.

You can chain as many if-else expressions together as needed. The combining if-else keyword is elif, which is used for every expression in between the first and the last expressions within a conditional statement.

The elif portion of the statement helps to ensure better readability of program logic. Too many if statements nested within each other can lead to programs that are difficult to maintain. The initial if expression is evaluated, and if it evaluates to False, the next elif expression is evaluated, and if it evaluates to False then the process continues. If any of the if or elif expressions evaluate to True then the statements within that portion of the if statement are processed. Eventually if all of the expressions evaluate to False then the final else expression is evaluated.

These next examples show a few ways for making use of a standard if-elif-else statement. Note that any expression can be evaluated in an if-elif-else construct. These are only some simplistic examples, but the logic inside the expressions could become as complex as needed.

*Listing 3-16. Standard if-elif-else*

Empty lists or strings will evaluate to False as well, making it easy to use them for comparison purposes in an if-elif-else statement.

*Listing 3-17. Evaluate Empty List*

### while Loop¶

Another construct that we touched upon in Chapter 1 was the loop. Every programming language provides looping implementations, and Python is no different. To recap, the Python language provides two main types of loops known as the while and the for loop.

The while loop logic follows the same semantics as the while loop in Java. The while loop evaluates a given expression and continues to loop through its statements until the results of the expression no longer hold true and evaluate to False. Most while loops contain a comparison expression such as x <= y or the like, in this case the expression would evaluate to False when x becomes greater than y. The loop will continue processing until the expression evaluates to False. At this time the looping ends and that would be it for the Java implementation. Python on the other hand allows an else clause which is executed when the loop is completed.

*Listing 3-18. Python while Statement*

This else clause can come in handy while performing intensive processing so that we can inform the user of the completion of such tasks. It can also be handy when debugging code, or when some sort of cleanup is required after the loop completes

*Listing 3-19. Resetting Counter Using with-else*

### continue Statement¶

The continue statement is to be used when you are within a looping construct, and you have the requirement to tell Python to continue processing past the rest of the statements in the current loop. Once the Python interpreter sees a continue statement, it ends the current iteration of the loop and goes on to continue processing the next iteration. The continue statement can be used with any for or while loop.

*Listing 3-20. Continue Statement*

In this example, whenever x is odd, the ‘continue’ causes execution to move on to the next iteration of the loop. When x is even, it is printed out.

### break Statement¶

Much like the continue statement, the break statement can be used inside of a loop. We use the break statement in order to stop the loop completely so that a program can move on to its next task. This differs from continue because the continue statement only stops the current iteration of the loop and moves onto the next iteration. Let’s check it out:

*Listing 3-21. Break Statement*

In the previous example, the loop termination condition is always True, so execution only leaves the loop when a break is encountered. If we are working with a break statement that resides within a loop that is contained in another loop (nested loop construct), then only the inner loop will be terminated.

### for Loop¶

The for loop can be used on any iterable object. It will simply iterate through the object and perform some processing during each pass. Both the break and continue statements can also be used within the for loop. The for statement in Python also differs from the same statement in Java because in Python we also have the else clause with this construct. Once again, the else clause is executed when the for loop processes to completion without any break intervention or raised exceptions. Also, if you are familiar with pre-Java 5 for loops then you will love the Python syntax. In Java 5, the syntax of the for statement was adjusted a bit to make it more in line with syntactically easy languages such as Python.

*Listing 3-22. Comparing Java and Python for-loop*

*Example of Java for-loop (pre Java 5)*

*Listing 3-23. Example of Python for-loop*

As you can see, the Python syntax is a little easier to understand, but it doesn’t really save too many keystrokes at this point. We still have to manage the index (x in this case) by ourselves by incrementing it with each iteration of the loop. However, Python does provide a built-in function that can save us some keystrokes and provides a similar functionality to that of Java with the automatically incrementing index on the for loop. The enumerate(sequence) function does just that. It will provide an index for our use and automatically manage it for us.

*Listing 3-24. Enumerate() Functionality*

If we do not require the use of an index, it can be removed and the syntax can be cleaned up a bit.

Now we have covered the program flow for conditionals and looping constructs in the Python language. However, good programming practice will tell you to keep it as simple as possible or the logic will become too hard to follow. In practicing proper coding techniques, it is also good to know that lists, dictionaries, and other containers can be iterated over just like other objects. Iteration over containers using the for loop is a very useful strategy. Here is an example of iterating over a dictionary object.

*Listing 3-25. Iteration Over Containers*

It is useful to know that we can also obtain the values of a dictionary object via each iteration by calling my_dict.values().

## Example Code¶

Let’s take a look at an example program that uses some of the program flow which was discussed in this chapter. The example program simply makes use of an external text file to manage a list of players on a sports team. You will see how to follow proper program structure and use spacing effectively in this example. You will also see file utilization in action, along with utilization of the raw_input() function.

*Listing 3-26. # import os module*

This example is packed full of concepts that have been discussed throughout the first three chapters of the book. As stated previously, the concept is to create and manage a list of sport players and their relative positions. The example starts by entering a while() loop that runs the program until the user enters the exit command. Next, the program checks to see if the ‘players.txt’ file exists. If it does, then the program prompts the user to enter a code to determine the next action to be taken. However, if the file does not exist then the user is forced to create at least one player/position pair in the file.

Continuing on, the program allows the user to enter as many player/position pairs as needed, or exit the program at any time. If the user chooses to manage the player/position list, the program simply opens the ‘players.txt’ file, uses a for() loop to iterate over each entry within the file. A dictionary is populated with the current player in each iteration of the loop. Once the loop has completed, the file is closed and the dictionary is iterated and printed. Exiting the program forces the else() clause to be invoked, which iterates over each player in the dictionary and writes them to the file.

Unfortunately, this program is quite simplistic and some features could not be implemented without knowledge of functions (Chapter 4) or classes (Chapter 6). A good practice would be to revisit this program once those topics have been covered and simplify as well as add additional functionality.

## Summary¶

All programs are constructed out of statements and expressions. In this chapter we covered details of creating expressions and using them. Expressions can be composed of any number of mathematical operators and comparisons. In this chapter we discussed the basics of using mathematical operators in our programs. The __future__ division topic introduced us to using features from the __future__. We then delved into comparisons and comparison operators.

We ended this short chapter by discussing proper program flow and properly learned about the if statement as well as how to construct different types of loops in Python. In the next chapter you will learn how to write functions, and the use of many built-in functions will be discussed.

**Augmented assignment** (or **compound assignment**) is the name given to certain assignmentoperators in certain programming languages (especially those derived from C). An augmented assignment is generally used to replace a statement where an operator takes a variable as one of its arguments and then assigns the result back to the same variable. A simple example is which is expanded to . Similar constructions are often available for various binary operators.

In general, in languages offering this feature, most operators that can take a variable as one of their arguments and return a result of the same type have an augmented assignment equivalent that assigns the result back to the variable in place, including arithmetic operators, bitshift operators, and bitwise operators.

## Discussion[edit]

For example, the following statement or some variation of it can be found in many programs:

x = x + 1This means "find the number stored in the variable *x*, add 1 to it, and store the result of the addition in the variable *x*." As simple as this seems, it may have an inefficiency, in that the location of variable *x* has to be looked up twice if the compiler does not recognize that two parts of the expression are identical: *x* might be a reference to some array element or other complexity. In comparison, here is the augmented assignment version:

With this version, there is no excuse for a compiler failing to generate code that looks up the location of variable *x* just once, and modifies it in place, if of course the machine code supports such a sequence. For instance, if x is a simple variable, the machine code sequence might be something like

and the same code would be generated for both forms. But if there is a special op code, it might be

MDM x,1meaning "Modify Memory" by adding 1 to x, and a decent compiler would generate the same code for both forms. Some machine codes offer INC and DEC operations (to add or subtract one), others might allow constants other than one.

More generally, the form is

x**?**= expression

where the **?** stands for some operator (not always **+**), and there may be no special op codes to help. There is still the possibility that if *x* is a complicated entity the compiler will be encouraged to avoid duplication in accessing *x*, and of course, if *x* is a lengthy name, there will be less typing required. This last was the basis of the similar feature in the ALGOL compilers offered via the Burroughs B6700 systems, using the tilde symbol to stand for the variable being assigned to, so that

would become

LongName:=x + sqrt(~)*7;and so forth. This is more general than just *x:=~ + 1;* Producing optimum code would remain the province of the compiler.

## Semantics[edit]

In expression-oriented programming languages such as C, assignment and augmented assignment are expressions, which have a value. This allows their use in complex expressions. However, this can produce sequences of symbols that are difficult to read or understand, and worse, a mistype can easily produce a different sequence of gibberish that although accepted by the compiler does not produce desired results. In other languages, such as Python, assignment and augmented assignment are statements, not expressions, and thus cannot be used in complex expressions. For example, the following is valid C, but not valid Python:

As with assignment, in these languages augmented assignment is a form of right-associative assignment.

## By language[edit]

### C descendants[edit]

In C, C++, and C#, the assignment operator is **=**, which is augmented as follows:

Operator | Description |
---|---|

Addition | |

Subtraction | |

Multiplication | |

Division | |

Modulus | |

Left bit shift | |

Right bit shift | |

Bitwise AND | |

Bitwise exclusive OR | |

Bitwise inclusive OR |

Each of these is called a *compound assignment* operator in said languages.^{[1]}^{[2]}^{[3]}

## Supporting languages[edit]

The following list, though not complete or all-inclusive, lists some of the major programming languages that support augmented assignment operators.

## 0 thoughts on “Augmented Assignment”

-->