-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create argument classes #109
base: main
Are you sure you want to change the base?
Conversation
Reviewer's Guide by SourceryThis pull request introduces a new file File-Level Changes
Tips
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @avkoll - I've reviewed your changes - here's some feedback:
Overall Comments:
- Consider simplifying the argument handling structure by merging
ArgumentMappings
functionality into theArguments
class, utilizing Pydantic's built-in alias feature to reduce duplication and improve maintainability. - Add comprehensive docstrings and comments to explain the purpose and functionality of each class and method, particularly for complex operations like
set_output_values
. - Proceed with writing tests for this new argument handling system to ensure its correctness and facilitate future maintenance and refactoring.
Here's what I looked at during the review
- 🟡 General issues: 5 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.
description="Show precipitation probability", | ||
) | ||
|
||
alias_map: ClassVar[dict[str, list[str]]] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider revising the alias mapping for clarity and consistency
The current alias mapping might lead to confusion, especially with aliases like 'hide_wave' for 'show_wave'. Consider using a more consistent naming scheme or restructuring this to make the relationship between aliases and their corresponding actions more explicit.
alias_map: ClassVar[dict[str, list[str]]] = {
"city": ["loc", "location"],
"show_wave": ["sw"],
"hide_wave": ["hw"],
return remapped_data | ||
|
||
""" | ||
TODO: write method to set location and update the dictionary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Remove or implement the TODO comment
TODO comments should not be left in production code. Either implement the method to set location and update the dictionary, or remove this comment if it's no longer relevant.
""" | ||
|
||
@classmethod | ||
def set_output_values(cls, args, arguments_dictionary: dict) -> dict: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Refactor to use alias_map and reduce code duplication
The set_output_values
method duplicates some of the logic from alias_map
. Consider refactoring this method to use alias_map
directly, which would reduce duplication and potential inconsistencies in the future.
def set_output_values(cls, args, arguments_dictionary: dict) -> dict: | |
@classmethod | |
def set_output_values(cls, args, arguments_dictionary: dict) -> dict: | |
return {cls.alias_map.get(arg, arg): value for arg, value in arguments_dictionary.items()} |
} | ||
|
||
@classmethod | ||
def generate_mappings(cls) -> dict[str, str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): Consider caching the result of generate_mappings
If generate_mappings
is called frequently, it might be more efficient to compute the result once and store it, rather than creating a new dictionary on each call.
@classmethod
@functools.lru_cache(maxsize=None)
def generate_mappings(cls) -> dict[str, str]:
return mappings | ||
|
||
@classmethod | ||
def parse_input(cls, data: dict) -> dict: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Handle potential key conflicts in parse_input
The parse_input
method doesn't handle the case where a key might be both a valid field name and an alias. Consider adding a check for this scenario to ensure consistent behavior.
def parse_input(cls, data: dict) -> dict: | |
@classmethod | |
def parse_input(cls, data: dict) -> dict: | |
alias_to_field_map = cls.generate_mappings() | |
field_to_alias_map = {v: k for k, v in alias_to_field_map.items()} | |
remapped_data = {} | |
for key, value in data.items(): | |
if key in alias_to_field_map: | |
remapped_data[alias_to_field_map[key]] = value | |
elif key in field_to_alias_map: | |
remapped_data[key] = value |
Nice work! Looks good to me, go ahead and start the integration. I'm able to help if you run into any blocks I left a brief review, I was confused on a couple lines |
|
||
alias_map: ClassVar[dict[str, list[str]]] = { | ||
"city": ["loc", "location"], | ||
"show_wave": ["sw", "hide_wave", "hw"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is show wave mapped to both "sw" (which i assume means "show wave") and "hide_wave"?
"city": ["loc", "location"], | ||
"show_wave": ["sw", "hide_wave", "hw"], | ||
"show_large_wave": ["slw"], | ||
"show_uv": ["suv", "hide_uv", "huv"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as show wave
"show_large_wave": ["slw"], | ||
"show_uv": ["suv", "hide_uv", "huv"], | ||
"show_height": ["sh", "hide_height", "hh"], | ||
"show_direction": ["sd", "hide_direction", "hdir"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as show wave
@avkoll |
gpt: bool = False | ||
|
||
|
||
class ArgumentMappings(BaseModel): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the implementation is as I expected, so it looks good!
If I may add a suggestion.
The fields in the ArgumentMappings
class overlap with those in the Arguments
class. Ideally, if possible, I think it would be better to consolidate all arguments into the Arguments
class and create the final mapping dictionary based on the contents of the Arguments
class.(For example, when implementing new arguments in the future, we would likely need to add fields to both classes, resulting in dual management, which could lead to reduced maintainability.)
However, I believe that realizing this would require modifications to the cli.py
file as well, which could potentially be a substantial amount of work. Therefore, I'll leave the decision on whether to implement this up to you :)
It's perfectly fine to keep this as a future refactoring phase if you prefer!
@ryansurf How do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, it would be ideal to reduce any redundancy.
cli.py
would indeed need to be revamped. Let us know what you want to do @avkoll !
I created the argument_types.py class file similar to what @K-dash had suggested but didn't want to start integrating it into the cli.py yet since that was a huge task. I was testing it by checking and verifying the output of the following code in run() in cli.py.
Example Usage:
I can write a test for this but wanted to open the PR incase anyone had any suggestions, if it looks good I can start writing the tests.
I wanted someone to check this before I started replacing stuff.
Summary by Sourcery
Add new classes
Arguments
andArgumentMappings
to manage and map command-line arguments with default values and multiple aliases. These classes include methods for parsing input and setting output values based on command-line arguments.New Features:
Arguments
class to define and manage various command-line arguments with default values.ArgumentMappings
class to handle multiple aliases for command-line arguments and provide methods for parsing input and setting output values.