HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Limited typecasting with regex

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withregextypecastinglimited

Problem

I'm learning Python, and found a fun little video on YouTube called "Learn Python through public data hacking". In essence it uses the CTA unofficial API to do some parsing of XML data. In taking things further than inline code, I'm chunking behaviors into modules and classes to further understand how Python works.

The XML from the API looks something like this:


1:40 AM

4194
22
East Bound
Northbound
E
41.88327006970422
-87.62828115689553
5421
Northbound
P238
Howard
49875
5314
7323287
0P
238





I'm using the python-requests module for the HTTP side, and once the XML is downloaded, I parse each ` node into a Bus class, assign each of the child nodes into a dictionary, and make that visible with a get(prop) statement, so I can just call bus.get('lat') to retrieve the latitude, etc. However, in order to do the correct calculations on it (i.e. arithmetic) each node's value needs to be returned as the correct type. By default, they're all read as strings.

Considering that Python doesn't have a "switch" statement like most other languages, someone at SO said to use a dictionary. Is this the/a correct way of doing something like this? Or is there some nifty builtin that I don't know of?

def dyncast(value):
_type = type(value)
types = {
"FloatType": (r'^[\d]{2}\.[\d]+$', lambda f : float(f)),
"IntType" : (r'^[\d]+$', lambda i : int(i)),
"StrType" : (r'^[a-zA-z]+$', lambda s : str(s))
}
for typeval in types:
pattern = types[typeval][0]
fn = types[typeval][1]
match = re.match(pattern, value)

# if it matches a regex and has a group(), return the
# lambda calculation (typecast)
if match and match.group():
return fn(value)

# return straight up if no matches
return value

# Called via:
for elm in n

Solution

Makes sense to me. A couple small things:

lambda f: float(f) should be equivalent to just float if I'm not mistaken. You can simplify the loop a bit too since you're not actually using the dictionary keys.

types = [
  (r'(regex)', float),
  (r'(regex)', int),
  (r'(regex)', str),
]
for pattern, fn in types:
  match = ...

Code Snippets

types = [
  (r'(regex)', float),
  (r'(regex)', int),
  (r'(regex)', str),
]
for pattern, fn in types:
  match = ...

Context

StackExchange Code Review Q#35813, answer score: 4

Revisions (0)

No revisions yet.