Skip to content
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

Aggregated Logbook #41

Closed
wants to merge 6 commits into from
Closed

Aggregated Logbook #41

wants to merge 6 commits into from

Conversation

gardaholm
Copy link
Contributor

as discussed in lemeryfertitta/Climbdex#55

slightly updated version of logbook_entries() functions from @PTschaikner to create an aggregated logbook logbook_entries_agg() with all needed informations which are used to get personal stats about the each climb ('climb_uuid', 'climb_name', 'board', 'date', 'is_mirror', 'angle', 'tries', 'sessions' 'time_since').

instead of the login credentials (user_id and password) logbook_entries_agg() uses user_id and token to fetch the results.

added bids_logbook_entries_agg to get an aggregated list of ascent and tries.
@@ -580,5 +581,115 @@ def logbook_entries(board, username, password, grade_type="font", db_path=None):

return full_logbook_df

def bids_logbook_entries_agg(board, token, user_id, db_path=None):
Copy link
Owner

@lemeryfertitta lemeryfertitta Aug 14, 2024

Choose a reason for hiding this comment

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

My suggestion in the other PR was that we could refactor that PR to adjust the params to get the output needed for the Climbdex changes. It looks like this PR just duplicates everything. E.g. we could refactor bids_logbook_entries to take a token instead of user/password and we can parametrize which columns are yielded to get the additional columns that this PR adds.

Seems like there is a lot of repeated code here that will be difficult to maintain in the future. Let me know if I'm missing something here and there is an issue with both features using the same underlying functions with slightly different parameters instead of duplicated functions with slightly altered functionality.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, we tried our best to refactor the function, see comment below.

Refactored logbook_entries function to allow console csv generation and generation of the aggregated files for climbdex within one function
@gardaholm
Copy link
Contributor Author

We refactored the function so the command boardlib logbook <board_name> --username=<username> --output=<output_file_name>.csv --grade-type="hueco" --database=<local_database_file> works like before (with username, password) and exports the logbook as csv.

To get the aggregated version of the logbook, which is used to calculate bids/attempts we use the same function logbook_entries() in get_bids(), but with the argument aggregate=true, see here
when aggregate is set to true then the logbook_entries() works with user_id and token from the cookie instead of the username and password from the terminal commands.

The refactor was a bit tricky, but all our tests worked.
In our climbdex+boardlib version we could tick a climb via the new menu item, and exporting the logbook via commandline showed the new entry in the csv file.


entries = api.logbook_entries(board, username, password, grade_type, db_path=database, aggregate=False)
for entry in entries:
if isinstance(entry, dict):
Copy link
Owner

Choose a reason for hiding this comment

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

Why do we need to add this check for these changes? When is entry not a dict?

@@ -1,17 +1,16 @@
import argparse
Copy link
Owner

@lemeryfertitta lemeryfertitta Aug 20, 2024

Choose a reason for hiding this comment

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

There are a lot of changes in this file, but it seems to me like at most this should just be a one-line change to add aggregate=False, but really there shouldn't be any changes at all because aggregate is already defaulting to False. Can we revert this file please? There are multiple regressions, e.g. to the command output prints, the imports, and the styling.


entry = {
"climb_uuid": raw_entry["climb_uuid"],
"board": board,
Copy link
Owner

Choose a reason for hiding this comment

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

Why does board need to be in the entry? It's already passed as an argument, so the caller already knows what the board is.


if aggregate:
Copy link
Owner

Choose a reason for hiding this comment

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

It doesn't seem like we really need to add this if clause at all. It's such a minor performance gain to drop a few fields from the aggregate version and perhaps we'd eventually want all of these fields in both versions anyways (for example, comment seems like something we'd eventually display).

user_id = login_info["user_id"]

bids_entries = list(bids_logbook_entries(board, username, password, db_path))
def logbook_entries(board, username, password=None, token=None, user_id=None, grade_type="font", db_path=None, aggregate=False):
Copy link
Owner

Choose a reason for hiding this comment

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

We don't need a function to support both forms of arguments. We should just have the command line call an extra function to fetch the token and then have logbook_entries require a token.

displayed_grade = convert_difficulty_to_grade(difficulty, grades_dict, grade_type)
if aggregate:
entry = {
'uid': f"{bid_row['climb_uuid']}-{bid_row['angle']}",
Copy link
Owner

Choose a reason for hiding this comment

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

Let's stay consistent with uuid, confusing to drop the u here. If you want, it could also be climb_angle_uuid to be more descriptive. Maybe I'm missing something here, but couldn't Climbdex construct the climb + angle ID on that end so that boardlib didn't need to worry about this nuance?

@@ -367,31 +365,42 @@ def get_bids_logbook(board, token, user_id):
sync_results = user_sync(board, token, user_id, tables=["bids"])
return sync_results["PUT"].get("bids", [])

def bids_logbook_entries(board, user_id, token, db_path=None, aggregate=False):
Copy link
Owner

@lemeryfertitta lemeryfertitta Aug 20, 2024

Choose a reason for hiding this comment

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

Can you explain what the goal is for the aggregate version? I thought the two changes needed for Climbdex were the UUID in the final output and the ability to use a token instead of username/password for auth. It seems like there is quite a bit more than this going on but it's a little hard to follow. I'm happy to make the changes as well if it seems cumbersome, just not sure exactly what differences are required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was probably thinking way too complicated here and went far off the beaten track. I'll think this through one more time and may start from scratch. I guess we should just add climb-uuid to output, change the auth-method to token and move the data transforming/aggregation to climbdex … sorry that this got a bit complicated or messed up here :)

Copy link
Owner

Choose a reason for hiding this comment

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

Sounds good and no worries, happy to help if needed!

@gardaholm gardaholm closed this Aug 22, 2024
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