advanced programming techniques now that we have seen the matcher coroutine we will look at how the matchers are usedand then we will look at the reporter(coroutine that receives the matchersoutputs tryfor file in sys argv[ :]print(filehtml open(fileencoding="utf "read(for matcher in matchersmatcher send(htmlfinallyfor matcher in matchersmatcher close(receiver close(the program reads the filenames listed on the command lineand for each one prints the filename and then reads the file' entire text into the html variable using the utf- encoding then the program iterates over all the matchers (three in this case)and sends the text to each of them each matcher then proceeds independentlysending each match it makes to the reporter coroutine at the end we call close(on each matcher and on the reporter--this terminates themsince otherwise they would continue (suspendedwaiting for text (or matches in the case of the reportersince they contain infinite loops @coroutine def reporter()ignore frozenset({"style css""favicon png""index html"}while truematch (yieldif match is not nonegroups match groupdict(if "urlin groups and groups["url"not in ignoreprint(url:"groups["url"]elif " in groupsprint( "groups[" "]elif " in groupsprint( "groups[" "]the reporter(coroutine is used to output results it was created by the statement receiver reporter(which we saw earlierand passed as the receiver argument to each of the matchers the reporter(waits (is suspendeduntil match is sent to itthen it prints the match' detailsand then it waits againin an endless loop--stopping only if close(is called on it using coroutines like this may produce performance benefitsbut does require us to adopt somewhat different way of thinking about processing