On my other blog, I wrote a post on how to extract the Python tutorials from Full Circle Magazine and join them in a single PDF.
For the lazy pigs, here is the PDF (6 MB). Get it while it’s hot :)
I wanted to download an html file with Python, store it in a temporary file, then convert this file to PDF by calling an external program.
#!/usr/bin/env python import os import tempfile temp = tempfile.NamedTemporaryFile(prefix='report_', suffix='.html', dir='/tmp', delete=False) html_file = temp.name (dirName, fileName) = os.path.split(html_file) fileBaseName = os.path.splitext(fileName) pdf_file = dirName + '/' + fileBaseName + '.pdf' print html_file # /tmp/report_kWKEp5.html print pdf_file # /tmp/report_kWKEp5.pdf # calling of HTML to PDF converter is omitted
See the documentation of
Solution #2 (update 20110303)
I had a problem with the previous solution. It works well in command-line, but when I tried to call that script in crontab, it stopped at the line “tempfile.NamedTemporaryFile”. No exception, nothing… So I had to use a different approach:
from time import time temp = "report.%.7f.html" % time() print temp # report.1299188541.3830960.html
The function time() returns the time as a floating point number. It may not be suitable in a multithreaded environment, but it was not the case for me. This version works fine when called from crontab.
- tempfile – Create temporary filesystem resources (post by Doug Hellmann with lots of examples)
- Python doc on tempfile
Update (20150712): if you need a temp. file name in the current directory:
>>> import tempfile >>> tempfile.NamedTemporaryFile(dir='.').name '/home/jabba/tmpKrBzoY'
Update (20150910): if you need a temp. directory:
import tempfile import shutil dirpath = tempfile.mkdtemp() # the temp dir. is created # ... do stuff with dirpath shutil.rmtree(dirpath)
This tip is from here.
“Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the
yield statement whenever they want to return data. Each time
next() is called, the generator resumes where it left-off (it remembers all the data values and which statement was last executed).”
Let’s rewrite our Fibonacci function using generators. In the previous approach, we specified how many Fibonacci numbers we want to get. The function calculated all of them and returned a list containing all the elements. With generators, we can calculate the numbers one by one. The new function will calculate a number, return it, and suspend its execution. When we call it again, it will resume where it left off and it runs until it computes another number, etc.
First let’s see a Fibonacci function that calculates the numbers in an infinite loop:
#!/usr/bin/env python def fib(): a, b = 0, 1 while True: print a # the current number is here a, b = b, a+b fib()
In order to rewrite it in the form of a generator, we need to locate the part where the current value is calculated. This is the line with
print a. We only need to replace this with
yield a. It means that the function will return this value and suspend its execution until called again.
So, with generators it will look like this:
#!/usr/bin/env python def fib(): a, b = 0, 1 while True: yield a a, b = b, a+b f = fib() for i in range(10): # print the first ten Fibonacci numbers print f.next(), # 0 1 1 2 3 5 8 13 21 34
It is also possible to get a slice from the values of a generator. For instance, we want the 5th, 6th, and 7th Fibonacci numbers:
#!/usr/bin/env python from itertools import islice def fib(): a, b = 0, 1 while True: yield a a, b = b, a+b for i in islice(fib(), 5, 8): print i # 5 8 13