title xml sax saxutils escape(titledescription xml sax saxutils escape(descriptionkeywords ",join([xml sax saxutils escape(kfor in keywords]if keywords else "stylesheet (stylesheet_template format(stylesheetif stylesheet else ""html html_template format(**locals()to get the copyright text we call str format(on the copyright_templatesupplying the year and name (suitably html-escapedas positional arguments to replace { and { for the title and description we produce html-escaped copies of their texts str format( for the html keywords we have two cases to deal withand we distinguish them using conditional expression if no keywords have been enteredwe set the keywords string to be the empty using otherwisewe use list comprehension to iterate over all the keywords to produce new list of stringswith each one being html-escaped this list is then joined into single string with comma separating each item using str join(the stylesheet text is created in similar way to the copyright textbut within the context of conditional expression so that the text is the empty string if no stylesheet is specified using str format(with mapping unpacking the html text is created from the html_templatewith keyword arguments used to provide the data for the replacement fields rather than the positional arguments used for the other template strings rather than pass each argument explicitly using key=value syntaxwe have used mapping unpacking on the mapping returned by locals(to do this for us (the alternative would be to write the format(call as format(title=titlecopyright=copyrightetc fh none tryfh open(filename" "encoding="utf "fh write(htmlexcept environmenterror as errprint("error"errelseprint("saved skeleton"filenamefinallyif fh is not nonefh close(once the html has been prepared we write it to the file with the given filename we inform the user that the skeleton has been saved--or of the error message if something went wrong as usual we use finally clause to ensure that the file is closed if it was opened