Archive
sprintf in Python 2
sprintf in Python
str = "pi is %.2f, name is %s" % (3.1415, "Boba") print str # pi is 3.14, name is Boba
Dictionary-based string formatting
myDict = {'solo': 'Han Solo',
'jabba': 'Jabba the Hutt'}
print "%(solo)s was captured by %(jabba)s." % myDict # Han Solo was captured by Jabba the Hutt.
Values are taken from the dictionary myDict. In the pattern you need to specify the keys in parentheses.
What is it good for? It’s more readable because otherwise when you see “%s” you have to check on the right side what it is, then you jump back with your eyes, etc. Python programming is serious stuff, not to be confused with a table tennis match! :)
Dictionary-based string formatting with locals
A variation of the previous solution:
solo = 'Han Solo'
jabba = 'Jabba the Hutt'
print locals()
# {'solo': 'Han Solo', '__builtins__': <module '__builtin__' (built-in)>, '__file__': './sprintf.py',
#'__package__': None, 'jabba': 'Jabba the Hutt', '__name__': '__main__', '__doc__': None}
print "%(solo)s was captured by %(jabba)s." % locals() # Han Solo was captured by Jabba the Hutt.
locals returns a copy of the local namespace as a dictionary where the keys are the variable names and the values are their respective values.
It means that in the pattern you can use the name of the variables and they will be replaced by their values.
Print in Python 2
Let’s see some examples how to print to the standard output:
#!/usr/bin/env python
import sys
a = "Alice"
b = "Bob"
print a # "Alice\n", i.e. newline added
print b # "Bob\n"
print a, b # "Alice Bob\n", i.e. space is used as separator
print a + b # "AliceBob\n", i.e. the two strings are concatenated
for i in range(10):
print i, # "0 1 2 3 4 5 6 7 8 9", i.e. no newline, but space is still added
# notice the comma after i
print # "\n"
age = 7.5
print "Alice is " + str(age) + " years old." # must use str() for converting
# the float to string
print "%s is %.1f years old" % (a, age) # like C's printf()
for i in range(10):
sys.stdout.write(str(i)) # "0123456789", now you have full control
print
Using the pprint module, you can “pretty print” any data structure. It’s similar to PHP’s print_r function.
import pprint pp = pprint.PrettyPrinter(indent=4) li = [] # some complicated structure pp.pprint(li)
How to print to the standard error? Easy:
#!/usr/bin/env python
import sys
sys.stderr.write("Reactor meltdown! Leave the building immediately!\n")
Creating and importing a module
If you have some functions that you use often, you can collect them in a module.
mymodule.py:
def f1(n):
return n + 1
How to use it (use-mymodule.py):
#!/usr/bin/env python import mymodule print mymodule.f1(5) # => 6 print mymodule.__name__ # => mymodule (note that .py is missing)
It is also possible to add some testing code to a module:
mymodule.py:
#!/usr/bin/env python
def f1(n):
return n + 1
if __name__ == "__main__":
number = 1977
print f1(number) # => 1978
Now, you can still import it like in use-mymodule.py, or you can launch it as if it were a standalone script. In the latter case the test suite will be executed. If you import it, the test suite is not executed. A test suite is a good practice to be sure that the module is working as expected.
Prison break
Exercise
The big boss of Montreal Prison celebrates his 50th birthday next week. For this special occasion he came up with the idea to let some prisoners go. In the prison there are 600 cells, one person in each. The cells are numbered from 1 to 600. The prison guard should go through all cells and open the doors. Then he goes to the 2nd cell and flips the lock at every second cell (that is, close the door if it was open and open it if it was closed). Then go the 3rd cell and flip the lock of every third cell, etc. This procedure should be repeated with every cell. Question: who are those lucky guys who get release, i.e. which cells remain open at the end?
Example with 8 cells:
00000000 initialization, all cells are closed 11111111 step 1, flip every lock 10101010 step 2, flip every 2nd lock 10001110 step 3, flip every 3rd lock 10011111 step 4, flip every 4th lock 10010111 step 5, flip every 5th lock 10010011 step 6, flip every 6th lock 10010001 step 7, flip every 7th lock 10010000 step 8, flip every 8th lock
Reverse an integer
Exercise
Take an integer and reverse its digits. The result is also an integer. Example: 83657 becomes 75638.
Solution
#!/usr/bin/env python
def reverse_int(n):
return int(str(n)[::-1])
n = 83657
print n # 83657
print reverse_int(n) # 75638
Summary: convert the number to string, reverse the string, then convert it back to integer. Details: 83657 -> str(83657) returns "83657" which is a string -> reverse it, we get "75638" -> int("75638") converts it to an integer.
Notes
If you want to concatenate a string and an integer, first you need to convert the integer to string. Example:
n = 83657 print "The value of n is " + n # error, won't work print "The value of n is " + str(n) # OK
Fibonacci numbers
Exercise
Now an easy one. Calculate the first N Fibonacci numbers, where F0 = 0, F1 = 1, …, Fn = Fn-1 + Fn-2. Write a function that receives N as a parameter and returns a list with the first N Fibonacci numbers. Example: fib(10) would produce [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]. Notice that F0 = 0 is included in the result.
Solution
#!/usr/bin/env python
# fibonacci.py
def fib(n):
assert(n >= 0)
li = []
a, b = 0, 1
for i in range(n+1):
li.append(a)
a, b = b, a+b
return li
if __name__ == "__main__":
print fib(10)
Here we solved the problem in an iterative way, but you can do it with recursive calls too.
Links
See http://www.scriptol.com/programming/fibonacci.php for a comprehensive list how to implement it in any language.
A to Z, then Z to A
Challenge
Write a Python script which prints the alphabet from “a” to “z”. Reverse its source code as explained in the previous post, i.e. reverse the order of lines and reverse the order of characters in each line. This reversed script should now print the alphabet from “z” to “a”!
Demonstration:
$ python fromAtoZ.py a b c d e f g h i j k l m n o p q r s t u v w x y z $ ./reverse-file.py fromAtoZ.py >za.py $ python za.py z y x w v u t s r q p o n m l k j i h g f e d c b a $ ./reverse-file.py za.py >az.py $ python az.py a b c d e f g h i j k l m n o p q r s t u v w x y z $ diff fromAtoZ.py az.py $
You can find the script reverse-file.py in my previous post. As you can see, applying reverse-file.py twice, you get back the original file.
Note that this challenge is not specific to Python. It can be solved in C++ too, for instance.
The solution is below, but first try to solve it yourself.
Read more…
Reverse a file
Exercise
Take a text file and reverse it the following ways: (1) reverse characters in each line, and (2) reverse the order of lines too. Let’s see an example:
Input:
#!/usr/bin/env python print "Please, reverse me completely!"
Output:
"!yletelpmoc em esrever ,esaelP" tnirp nohtyp vne/nib/rsu/!#
Autoflush
Printing to the standard output is buffered. What to do if you want to see the output immediately?
import sys import os # reopen stdout file descriptor with write mode # and 0 as the buffer size (unbuffered) sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) print "unbuffered text"
Credits
Update (20130206)
The solution above switches buffered mode off, but you can’t switch it back on because you lose the original sys.stdout file descriptor. I have a more sophisticated solution, available here (autoflush.py) as part of my jabbapylib library.
Usage #1:
autoflush(True) # text that you want to print in unbuffered mode comes here autoflush(False) # back to normal
Usage #2:
# using a context manager
with AutoFlush():
# unbuffered text comes here
sys.stdout.write(...)
# here you are back to normal
Let’s not forget the simplest and most trivial solution either:
sys.stdout.write(...) sys.stdout.flush() # flush out immediately
Update (20210827)
Here is a Python 3 solution:
# auto-flush
sys.stdout = io.TextIOWrapper(
open(sys.stdout.fileno(), 'wb', 0),
write_through=True
)
StringBuilder functionality in Python
Problem
You need to concatenate lots of string elements. Under Java we use a StringBuilder for this, but how to do that in Python?
Solution #1
Use a list, and join the elements of the list at the end. This is much more efficient than concatenating strings since strings are immutable objects, thus if you concatenate a string with another, the result is a NEW string object (the problem is the same with Java strings).
Example:
def g():
sb = []
for i in range(30):
sb.append("abcdefg"[i%7])
return ''.join(sb)
print g() # abcdefgabcdefgabcdefgabcdefgab
Solution #2 (update 20120110)
Use a StringIO object and print to it. In short:
from cStringIO import StringIO out = StringIO() print >>out, 'arbitrary text' # 'out' behaves like a file return out.getvalue()

You must be logged in to post a comment.