the singleton pattern if you look at the output of the _test_error_log py__ functionyou will see that the message now has the level added to the line as prefix[errorsomething went wrong our logging project now has some really useful functionalitybut bet there is something bothering you about the way the logger py file is written that alarm bell in your head just went offdid it notif it didyou are completely rightwe should not be copying the same instructions to open the file and append the message to the filewith only the prefix string differing for each function let' refactor our code so we don' repeat ourselves the part that is repeated is the part we want to extract from all the methods duplicating the code the next step is to generalize the function enough so that every function can use it without losing any of its original functionality in each of the repeated functionsthe prefix was the only thing that differed from function to function soif we were to write function that takes the message and level as parameterswe could use this function in each of the other functions and reduce it to single line of code in each case we now have shorterclearer logger to use in our other projects logger py def write_log(levelmsg)with open("/var/log/filename log"" "as log_filelog_file write("[{ }{ }\nformat(levelmsg)def critical(msg)write_log("critical",msgdef error(msg)write_log("error"msgdef warn(msg)write_log("warn"msgdef info(msg)write_log("info"msgdef debug(msg)write_log("debug"msg