import re
import string
def buildRule((pattern, search, replace)):
return lambda word: re.search(pattern, word) and re.sub(search, replace, word)
def plural(noun, language='en'):
lines = file('rules.%s' % language).readlines()
patterns = map(string.split, lines)
rules = map(buildRule, patterns)
for rule in rules:
result = rule(noun)
if result: return result
if __name__ == '__main__':
import sys
if sys.argv[1:]:
print plural(sys.argv[1])
else:
print __doc__
You're still using the closures technique here (building a function dynamically that uses variables defined
outside the function), but now you've combined the separate match and apply functions into one.
Our plural function now takes an optional second parameter, language, which defaults to en.
You use the language parameter to construct a filename, then open the file and read the contents into a list. If
language is en, then you'll open the rules.en file, read the entire thing, break it up by carriage returns,
and return a list. Each line of the file will be one element in the list.
As you saw, each line in the file really has three values, but they're separated by whitespace (tabs or spaces, it
makes no difference). Mapping the string.split function onto this list will create a new list where each
element is a tuple of three strings. So a line like [sxz]$ $ es will be broken up into the tuple
('[sxz]$', '$', 'es').
If patterns is a list of tuples, then rules will be a list of the functions created dynamically by each call to
buildRule. Calling buildRule(('[sxz]$', '$', 'es')) returns a function that takes a single
parameter, word. When this returned function is called, it will execute re.search('[sxz]$', word)
and re.sub('$', 'es', word).
Because you're now building a combined match−and−apply function, you need to call it differently. Just call
the function, and if it returns something, then that's the plural; if it returns nothing (None), then the rule didn't
match and you need to try another rule.
import string
def buildRule((pattern, search, replace)):
return lambda word: re.search(pattern, word) and re.sub(search, replace, word)
def plural(noun, language='en'):
lines = file('rules.%s' % language).readlines()
patterns = map(string.split, lines)
rules = map(buildRule, patterns)
for rule in rules:
result = rule(noun)
if result: return result
if __name__ == '__main__':
import sys
if sys.argv[1:]:
print plural(sys.argv[1])
else:
print __doc__
You're still using the closures technique here (building a function dynamically that uses variables defined
outside the function), but now you've combined the separate match and apply functions into one.
Our plural function now takes an optional second parameter, language, which defaults to en.
You use the language parameter to construct a filename, then open the file and read the contents into a list. If
language is en, then you'll open the rules.en file, read the entire thing, break it up by carriage returns,
and return a list. Each line of the file will be one element in the list.
As you saw, each line in the file really has three values, but they're separated by whitespace (tabs or spaces, it
makes no difference). Mapping the string.split function onto this list will create a new list where each
element is a tuple of three strings. So a line like [sxz]$ $ es will be broken up into the tuple
('[sxz]$', '$', 'es').
If patterns is a list of tuples, then rules will be a list of the functions created dynamically by each call to
buildRule. Calling buildRule(('[sxz]$', '$', 'es')) returns a function that takes a single
parameter, word. When this returned function is called, it will execute re.search('[sxz]$', word)
and re.sub('$', 'es', word).
Because you're now building a combined match−and−apply function, you need to call it differently. Just call
the function, and if it returns something, then that's the plural; if it returns nothing (None), then the rule didn't
match and you need to try another rule.
Comments
Post a Comment
https://gengwg.blogspot.com/