I had to embed 50 pictures in a pdf file for print - don't ask me why. Dependencies (on Debian):
- apt-get install imagemagick
- apt-get install pdftk
This is the Python script. It uses commands "montage" (from imagemagick) and pdftk:
- from subprocess import call
- import os
- folder = 'pictures'
- print "Work in progress..."
- files = os.listdir(folder)
- pages = [files[i:i+images_per_page] for i in range(0, len(files), images_per_page)]
- pages_names = 
- for i in range(0, len(pages)):
- montage = ['montage']
- print "generating page " + str(i)
- files_in_page = [folder + os.sep + j for j in pages[i]]
- montage.extend(['-mode', 'Concatenate', '-tile', str(columns) + 'x'])
- output_page = folder + os.sep + 'page' + str(i) + '.pdf'
- pdftk = ['pdftk']
- pdftk.extend(['cat', 'output', 'output.pdf'])
There are many ways to work with collections. We are following Microsoft Guidelines for Collections plus some ideas that Kent Beck explains in Implementation Patterns. I've created a repository with code examples so that anyone can play with them. All the unit tests in the project are green except for two, which are red on purpose to express my surprise when I wrote them, because it's a behavior I didn't expect.
IEnumerable<T> is not dangerous itself, the surprise may come up when the variable is created via a LINQ expression (.Select, .Where ...). Then it may be the case that the query execution is deferred and the behavior of the code is totally unexpected. For this reason we try to avoid IEnumerable<T> and IQueryable<T> as the return type of functions.
Try not to expose collections as much as you can by wrapping them within objects you own which expose only the minimum domain required features. But if you have to expose the collection anyway, in our teams the convention is:
Good code expresses the programmer's intent, this is why we choose from the three types above to return collections when we have to.
When it comes to parameters, it's OK to use IEnumerable<T> as a parameter because it's the most generic collection type. Although the caller could send an unresolved Linq query as an argument hidden in the form of a IEnumerable<T>, the method does not have to be defensive about it (in most cases).
Other built-in collections like List<T> are intended to be used internally, only for implementation. So it's OK for a private method to return List<T>. The type Collection<T> actually implements IList<T> so I can't find a good reason right now to use Collection<T> instead of just List<T>.