Skip to content

Noah Marcus DataMade Code Challenge#1

Open
noah-marcus wants to merge 4 commits intomasterfrom
nm-code-challenge
Open

Noah Marcus DataMade Code Challenge#1
noah-marcus wants to merge 4 commits intomasterfrom
nm-code-challenge

Conversation

@noah-marcus
Copy link
Owner

DataMade Code Challenge Submission

This is my submission for the DataMade Code Challenge!

Copy link

@beamalsky beamalsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @noah-marcus! I'm Bea, and I'll be reviewing your code challenge and co-interviewing you with Derek this week.

Lots of good stuff here. I found your code clear to read and appreciated the thorough commenting on your thought processes, though I'd like to see explicit testing instructions in your README. I left a few additional comments inline, and a couple ways you could improve your error handling.

We'd like you to respond to the review and make the requested changes before your interview, if time allows. For guidance, we like and try to stick to Thoughtbot's guide to code review when working together on pull requests.

Let me know in the relevant thread if you have any questions, etc., and I'll be sure to get back to you ASAP. Look forward to talking more tomorrow.


**Note:** You can use the following address strings for testing during implementation:

- ✅ Valid: `123 main st chicago il`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In condensing this README, you lost the testing instructions! Could you add these test strings back, either in this README or in your PR description? For reference, here's DataMade's pull request template.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! Thanks for catching that. I added it back into the README. Change has been committed here.

returns the expected output.

You can run the tests using Docker:
You can run some tests using Docker:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd appreciate a description of precisely what these tests are looking for. Could you expand this section?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. I added some more details here. Please let me know if you think I should add more detail!

</table>
</div>
<div id="parse-error" class="alert alert-danger mt-2 text-center" style="display:none" role="alert">
Uh-oh -- The inputted address could not be parsed!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job anticipating the edge case of an empty string submission 👍

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

class AddressParse(APIView):
renderer_classes = [JSONRenderer]

# parse requested address string and return components to frontend

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job documenting the types, but this could be a docstring! Could you create one for both this function and parse()?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing that out, my knowledge of Python conventions is not my strongest asset 😳. Here is my attempt at converting my comments to docstrings.

address_string = '123 main st chicago il'
pytest.fail()

expected_return_input_string = '123 main st chicago il'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this assigned separately from address_string above?

Copy link
Owner Author

@noah-marcus noah-marcus Oct 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I understand why that is confusing. I made that choice for my own visual preference. When writing my tests, I like to compartmentalize what I am giving to the test and what I expect in return.

Since there is an intended overlap (the expected return string should be the given address string), my expected_return_input_string is redundant and does not need to be assigned separately. I'll fix that up!

Edit: Change has been committed!


expected_return_input_string = '123 main st chicago il'
expected_return_address_components = OrderedDict([('AddressNumber', '123'), ('StreetName', 'main'), ('StreetNamePostType', 'st'), ('PlaceName', 'chicago'), ('StateName', 'il')])
excpected_return_address_type = 'Street Address'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you've got a typo in the variable name here.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I need to install a spell checker into my IDE! (Updated here)

assert response.data['input_string'] == expected_return_input_string
assert response.data['address_components'] == expected_return_address_components
assert response.data['address_type'] == excpected_return_address_type
# pytest.fail()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this commented-out code.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 (Updated here)

var input_string = $('#address').val();

// only parse input if user inputted something
if (input_string != ""){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user submits a string of spaces (eg, ' '), this is the result:

Screen Shot 2020-10-13 at 11 26 52 AM

How can you handle that case so that this submit function treats it as an empty string?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have never thought of that edge case, thanks! I added .trim() to when I capture the input. Commit is here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 👍

# pass request address to parse method
try:
address_components, address_type = self.parse(input_string)
except Exception as e:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at e here there are more details on the error. For example, by inserting print(str(e)) in this except block and submitting 123 main st chicago il 123 main to the form I can see:

parserator  | ERROR: Unable to tag this string because more than one area of the string has the same label
parserator  |
parserator  | ORIGINAL STRING:  123 main st chicago il 123 main
parserator  | PARSED TOKENS:    [('123', 'AddressNumber'), ('main', 'StreetName'), ('st', 'StreetNamePostType'), ('chicago', 'PlaceName'), ('il', 'StateName'), ('123', 'AddressNumber'), ('main', 'StreetName')]
parserator  | UNCERTAIN LABEL:  AddressNumber
parserator  |
parserator  | When this error is raised, it's likely that either (1) the string is not a valid person/corporation name or (2) some tokens were labeled incorrectly
parserator  |
parserator  | To report an error in labeling a valid name, open an issue at https://github.com/datamade/usaddress/issues/new - it'll help us continue to improve probablepeople!
parserator  |
parserator  | For more information, see the documentation at https://usaddress.readthedocs.io/

Could you capture this error message and display it on the frontend in a way that's useful to a user?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was struggling with figuring out what message to pass on to the user and was not sure how much information was too much. In this commit here, I am now capturing the entire message and displaying it on the frontend. I think the benefit to this approach is that the user will always receive a detailed and specific message from the backend.

Also, I'm not sure how to capture this new message for the unit test check? The commit above is a work in progress because the error handling is failing. @beamalsky, any advice?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some room for personal style here, and you don't know who your users are in this theoretical app so what you included as an error message is definitely reasonable.

One way I've handled returning the full error code without overwhelming users is to have a human-friendly error on top, and then the error stashed in under a "See more" collapsed section.

Instead of returning a ParseError for a bad request, you could return a Response with a 400 error code. Something like this:

return Response({
	'input_string': addr, 
	'address_components': '', 
	'address_type': '', 
	'error' : str(e)}, 
	status=400
)

That way, you'll have access to the full error text from usaddress under error and a Response to test the attributes of in your test in a way that mirrors successful submission.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes a lot of sense, thanks for clearing that up! I updated my code in this commit and the test is working again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants