<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 "Gematria" is a system for assigning a number to a word by summing the numeric values of each of the letters as defined by the Mispar godol (https
Step1:  To implement an ASCII version of gematria in Python, we need to turn each letter into a number and add them all together.  So, to start, note that Python can use a for loop to cycle through all the members of a list (in order)
Step2:  A "word" is simply a list of characters, so we can iterate over it just like a list of numbers
Step3:  Let's print the ordinal (ASCII) value instead
Step4:  Now let's create a variable to hold the running sum of the values
Step5:  Another way could be to create another list to hold the values and then use the sum function
Step6:  We can use a map function to transform all the characters via the ord function. This is interesting because map is a function that takes another function as its first argument. The second is a list of items to feed into the function. The result is the transformed list. For instance, we can use the str.upper function to turn each letter (e.g., "p") into the upper-case version ("P"). NB
Step7:  Now we can sum those numbers
Step8:  Now let's think about how we could apply this to all the words in a file. As above, we can use a for loop to iterate over all the lines in a file
Step9:  The original is single-spaced, so why is this printing double-spaced? The for loop reads each "line" which is a string of text up to and including a newline ("\n"). The print by default adds a newline, so we either need to print(line, end='') to indicate we don't want anything at the end
Step10:  Or we need to use the rstrip function to "strip" whitespace off the "r"ight side of the line
Step11:  We can use the split function to get all the words for each line and a for loop to iterate over those
Step12:  We want to get rid of anything that is not character like the punctuation. There is a function in the str library called isalpha that returns True or False
Step13:  Each x in the loop is itself a string, so we can call the method directly on the variable
Step14:  Similar to what we saw above with the map function, we can use filter to find all the characters in a string which are True for isalpha. filter is another "higher-order function" that takes another function for its first argument (called the "predicate") and a list as the second argument. Whereas map returns all the elements of the list transformed by the function, filter returns only those for which the predicate is true.
Step15:  The first argument for map and filter is called the "lambda," and sometimes you will see it written out explicitly like so
Step16:  Here is a way to find only even numbers
Step17:  Let's turn that list of characters back into a word with the join function
Step18:  So, going back to our Gettysburg example, here is a list of all the words without punctuation
Step19:  Now, rather let's print the sum of the chr values for each cleaned up word
Step20:  Notice that we are calling rstrip for every line, so we could easily move that into a map, and the "cleaning" code can likewise be moved into a map
Step21:  At this point, we have arguably sacrificed readability for the sake of using map and filter -- another instance of "just because you can doesn't mean you should"! 
We can improve readability, however, by creating our own functions with informative names
Step22:  With this, I hope you're now understand what is meant by a "higher-order function" (functions that take other functions as arguments) and how they can streamline your code.
Exercise
<ASSISTANT_TASK:>
Python Code:
print('"{}" = "{}"'.format('A', ord('A')))
print('"{}" = "{}"'.format('a', ord('a')))
print('"{}" = "{}"'.format(88, chr(88)))
print('"{}" = "{}"'.format(112, chr(112)))
Explanation: "Gematria" is a system for assigning a number to a word by summing the numeric values of each of the letters as defined by the Mispar godol (https://en.wikipedia.org/wiki/Gematria). For English characters, we can use the ASCII table (https://en.wikipedia.org/wiki/ASCII). It is not necessary, however, to encode this table in our program as Python provides the ord function to convert a character to its "ordinal" (order in the ASCII table) value as well as the chr function to convert a number to its "character."
End of explanation
for n in range(5):
    print(n)
for char in ['p', 'y', 't', 'h', 'o', 'n']:
    print(char)
Explanation: To implement an ASCII version of gematria in Python, we need to turn each letter into a number and add them all together.  So, to start, note that Python can use a for loop to cycle through all the members of a list (in order):
End of explanation
for char in "python":
    print(char)
Explanation: A "word" is simply a list of characters, so we can iterate over it just like a list of numbers:
End of explanation
for char in "python":
    print('"{}" = "{}"'.format(char, ord(char)))
Explanation: Let's print the ordinal (ASCII) value instead:
End of explanation
word = "python"
total = 0
for char in word: 
    total += ord(char)
print('"{}" = "{}"'.format(word, total))
Explanation: Now let's create a variable to hold the running sum of the values:
End of explanation
word = "python"
all = []
for char in word: 
    all.append(ord(char))
print(all)
print('"{}" = "{}"'.format(word, sum(all)))
Explanation: Another way could be to create another list to hold the values and then use the sum function:
End of explanation
list(map(str.upper, "python"))
list(map(ord, "python"))
Explanation: We can use a map function to transform all the characters via the ord function. This is interesting because map is a function that takes another function as its first argument. The second is a list of items to feed into the function. The result is the transformed list. For instance, we can use the str.upper function to turn each letter (e.g., "p") into the upper-case version ("P"). NB: it's necessary to force the results into a list.
End of explanation
sum(map(ord, "python"))
Explanation: Now we can sum those numbers:
End of explanation
for line in open('gettysburg.txt'):
    print(line)
Explanation: Now let's think about how we could apply this to all the words in a file. As above, we can use a for loop to iterate over all the lines in a file:
End of explanation
for line in open('gettysburg.txt'):
    print(line, end='')
Explanation: The original is single-spaced, so why is this printing double-spaced? The for loop reads each "line" which is a string of text up to and including a newline ("\n"). The print by default adds a newline, so we either need to print(line, end='') to indicate we don't want anything at the end:
End of explanation
for line in open('gettysburg.txt'):
    print(line.rstrip())
Explanation: Or we need to use the rstrip function to "strip" whitespace off the "r"ight side of the line:
End of explanation
for line in open('gettysburg.txt'):
    for word in line.rstrip().split():
        print(word)
Explanation: We can use the split function to get all the words for each line and a for loop to iterate over those:
End of explanation
for x in "a8,X.b!G":
    print('"{}" = "{}"'.format(x, str.isalpha(x)))
Explanation: We want to get rid of anything that is not character like the punctuation. There is a function in the str library called isalpha that returns True or False:
End of explanation
for x in "a8,X.b!G":
    print('"{}" = "{}"'.format(x, x.isalpha()))
Explanation: Each x in the loop is itself a string, so we can call the method directly on the variable:
End of explanation
list(filter(str.isalpha, "a8,X.b!G"))
Explanation: Similar to what we saw above with the map function, we can use filter to find all the characters in a string which are True for isalpha. filter is another "higher-order function" that takes another function for its first argument (called the "predicate") and a list as the second argument. Whereas map returns all the elements of the list transformed by the function, filter returns only those for which the predicate is true.
End of explanation
list(filter(lambda char: char.isalpha(), "a8,X.b!G"))
Explanation: The first argument for map and filter is called the "lambda," and sometimes you will see it written out explicitly like so:
End of explanation
list(filter(lambda x: x % 2 == 0, range(10)))
Explanation: Here is a way to find only even numbers:
End of explanation
''.join(filter(str.isalpha, "a8,X.b!G"))
Explanation: Let's turn that list of characters back into a word with the join function:
End of explanation
for line in open('gettysburg.txt'):
    for word in line.rstrip().split():
        print(''.join(filter(str.isalpha, word)))
Explanation: So, going back to our Gettysburg example, here is a list of all the words without punctuation:
End of explanation
for line in open('gettysburg.txt'):
    for word in line.rstrip().split():
        clean = ''.join(filter(str.isalpha, word))
        print('"{}" = "{}"'.format(clean, sum(map(ord, clean))))
Explanation: Now, rather let's print the sum of the chr values for each cleaned up word:
End of explanation
for line in map(str.rstrip, open('gettysburg.txt')):
    for word in map(lambda w: ''.join(filter(str.isalpha, w)), line.split()):
        print('"{}" = "{}"'.format(word, sum(map(ord, word))))
Explanation: Notice that we are calling rstrip for every line, so we could easily move that into a map, and the "cleaning" code can likewise be moved into a map:
End of explanation
def onlychars(word):
    return ''.join(filter(str.isalpha, word))
def word2num(word):
    return sum(map(ord, word))
for line in map(str.rstrip, open('gettysburg.txt')):
    for word in map(onlychars, line.split()):
        print('"{}" = "{}"'.format(word, word2num(word)))
Explanation: At this point, we have arguably sacrificed readability for the sake of using map and filter -- another instance of "just because you can doesn't mean you should"! 
We can improve readability, however, by creating our own functions with informative names:
End of explanation
from collections import defaultdict
def onlychars(word):
    return ''.join(filter(str.isalpha, word))
file = '/usr/share/dict/words'
num2word = defaultdict(list)
for line in map(str.rstrip, open(file)):
    for word in map(onlychars, line.split()):
        num = sum(map(ord, word))
        num2word[num].append(word)
count_per_n = []
for n, wordlist in num2word.items():
    count_per_n.append((len(wordlist), n))
top10 = list(reversed(sorted(count_per_n)))[:10]
for (num_of_words, n) in top10:
    print('"{}" = {}'.format(n, ', '.join(num2word[n])))
Explanation: With this, I hope you're now understand what is meant by a "higher-order function" (functions that take other functions as arguments) and how they can streamline your code.
Exercise: read your local dictionary (e.g., "/usr/share/dict/words") and find how many words share the same numeric representation.
End of explanation
<END_TASK>