-
Notifications
You must be signed in to change notification settings - Fork 0
/
typedetector.py
120 lines (94 loc) · 3.15 KB
/
typedetector.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
# coding: utf-8
import math
import re
import datetime
class TypeDetector(object):
""" TypeDetector class
"""
NONE = 0
INTEGER = 1
FLOAT = 2
LOCATION_LONG = 3
LOCATION_LAT = 4
DATE = 5
STRING = 6
re_location = re.compile(u'^(\d{1,3})°(\d{1,2})\'(?:(\d{1,2})(?:\.(\d+))?\")?([NSEW])$')
re_date = re.compile('^(?:(\d{4})-(\d{1,2})-(\d{1,2}))|(?:(\d{4})/(\d{1,2})/(\d{1,2}))$')
def __init__(self, s):
self._type = TypeDetector.NONE
self._typeValue = None
self._value = s
self._checkType(s)
def _checkType(self, s):
""" Detect type inside string and converts value to detected type
"""
try:
self._typeValue = int(s)
self._type = TypeDetector.INTEGER
return
except:
pass
try:
self._typeValue = float(s)
self._type = TypeDetector.FLOAT
return
except:
pass
if self._checkLocation(s):
return
if self._checkDate(s):
return
self._typeValue = s
self._type = TypeDetector.STRING
def _checkDate(self, s):
m = re.match(TypeDetector.re_date, s)
if m is None:
return False
if m.group(1) is not None:
year, month, day = m.group(1), m.group(2), m.group(3)
else:
year, month, day = m.group(4), m.group(5), m.group(6)
try:
self._typeValue = datetime.date(int(year), int(month), int(day))
self._type = TypeDetector.DATE
return True
except ValueError:
pass
return False
def _checkLocation(self, s):
""" Checks if string has location format
"""
m = re.match(TypeDetector.re_location, s)
if m is None:
return False
deg_angle = float(m.group(1)) + float(m.group(2)) / 60.0
if m.group(3) is not None:
if m.group(4) is not None:
deg_angle += float(m.group(3) + '.' + m.group(4)) / 3600.0
else:
deg_angle += float(m.group(3)) / 3600.0
if m.group(5) == 'W':
self._type = TypeDetector.LOCATION_LONG
self._typeValue = -deg_angle
elif m.group(5) == 'E':
self._type = TypeDetector.LOCATION_LONG
self._typeValue = deg_angle
elif m.group(5) == 'N':
self._type = TypeDetector.LOCATION_LAT
self._typeValue = deg_angle
else:
self._type = TypeDetector.LOCATION_LAT
self._typeValue = -deg_angle
return True
def isNumber(self):
return self._type in { TypeDetector.INTEGER, TypeDetector.FLOAT }
def getValue(self):
return self._value
def getType(self):
return self._type
def getTypeValue(self):
return self._typeValue
def getRadAngle(self):
if self._type in { TypeDetector.LOCATION_LONG, TypeDetector.LOCATION_LAT }:
return math.pi * self.getTypeValue(self) / 180.0
return None