-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
132 lines (101 loc) · 3.42 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"Utility functions for file and string manipulation"
import string
from math import sqrt
############################
# String utility functions #
############################
def lines_from_file(path):
"""Return a list of strings, one for each line in a file."""
with open(path, 'r') as f:
return [line.strip() for line in f.readlines()]
def remove_punctuation(s):
"""Return a string with the same contents as s, but with punctuation removed.
>>> remove_punctuation("It's a lovely day, don't you think?")
'Its a lovely day dont you think'
>>> remove_punctuation("Its a lovely day dont you think")
'Its a lovely day dont you think'
"""
punctuation_remover = str.maketrans('', '', string.punctuation)
return s.strip().translate(punctuation_remover)
def lower(s):
"""Return a lowercased version of s.
>>> lower("HELLO")
'hello'
>>> lower("World")
'world'
>>> lower("hello WORLD")
'hello world'
"""
return s.lower()
def split(s):
"""Return a list of words contained in s, which are sequences of characters
separated by whitespace (spaces, tabs, etc.).
>>> split("It's a lovely day, don't you think?")
["It's", 'a', 'lovely', 'day,', "don't", 'you', 'think?']
"""
return s.split()
#############################
# Keyboard layout functions #
#############################
KEY_LAYOUT = [["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "="],
["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]"],
["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'"],
["z", "x", "c", "v", "b", "n", "m", ",", ".", "/"],
[" "]]
def distance(p1, p2):
"""Return the Euclidean distance between two points
The Euclidean distance between two points, (x1, y1) and (x2, y2)
is the square root of (x1 - x2) ** 2 + (y1 - y2) ** 2
>>> distance((0, 1), (1, 1))
1.0
>>> distance((1, 1), (1, 1))
0.0
>>> round(distance((4, 0), (0, 4)), 3)
5.657
"""
return sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
def get_key_distances():
"""Return a new dictionary mapping key pairs to distances.
Each key of the dictionary is a tuple of two
letters as strings, and each value is the euclidean distance
between the two letters on a standard QWERTY keyboard, normalized
The scaling is constant, so a pair of keys that are twice
as far have a distance value that is twice as great
>>> distances = get_key_distances()
>>> distances["a", "a"]
0.0
>>> round(distances["a", "d"],3)
1.367
>>> round(distances["d", "a"],3)
1.367
"""
key_distance = {}
def compute_pairwise_distances(i, j, d):
for x in range(len(KEY_LAYOUT)):
for y in range(len(KEY_LAYOUT[x])):
l1 = KEY_LAYOUT[i][j]
l2 = KEY_LAYOUT[x][y]
d[l1, l2] = distance((i, j), (x, y))
for i in range(len(KEY_LAYOUT)):
for j in range(len(KEY_LAYOUT[i])):
compute_pairwise_distances(i, j, key_distance)
max_value = max(key_distance.values())
return {key: value * 8 / max_value for key, value in key_distance.items()}
def count(f):
"""Keeps track of the number of times a function f is called using the
variable call_count
>>> def factorial(n):
... if n <= 1:
... return 1
... return n * factorial(n - 1)
>>> factorial = count(factorial)
>>> factorial(5)
120
>>> factorial.call_count
5
"""
def counted(*args):
counted.call_count += 1
return f(*args)
counted.call_count = 0
return counted