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
|
#!/usr/bin/python
import io
import re
from tokenize import tokenize
def get_tokens(code):
""" Gets a list of tokens. """
stream = io.BytesIO(code.encode('utf-8'))
return [t.string for t in tokenize(stream.readline) if t.string]
# Check if tokens contain a sequence of tokens (given as a list of strings).
def has_token_sequence(tokens, sequence):
for i in range(len(tokens)-len(sequence)+1):
if tokens[i:i+len(sequence)] == sequence:
return True
return False
def almost_equal(a, b, prec=1):
""" Compares values a and b using at most <code>prec</code> decimal values. """
return int(a*10**prec) == int(b*10**prec)
def get_numbers(s):
""" Extracts numbers from string s. """
str_vals = re.findall(r'''
[-+]? # optional sign
(?:
(?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
|
(?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
)
# followed by optional exponent part if desired
(?: [Ee] [+-]? \d+ ) ?
''', s, re.VERBOSE)
return [float(v) for v in str_vals]
def string_almost_equal(s, a, prec=1):
""" Searches string s for a value that is almost equal to a. """
for v in get_numbers(s):
if almost_equal(v, a, prec):
return True
return False
def string_contains_number(s, a):
""" Searches string s for a value that is equal to a. """
return a in get_numbers(s)
if __name__ == '__main__':
print(has_token_sequence('x + y >= 0', ['>=', '0']))
print(has_token_sequence('x + y > 0', ['>=', '0']))
|