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

Improve how sub-commands are called. #53

Open
remochristen opened this issue Dec 17, 2024 · 3 comments
Open

Improve how sub-commands are called. #53

remochristen opened this issue Dec 17, 2024 · 3 comments
Labels

Comments

@remochristen
Copy link
Contributor

Currently the entire args object is passed to the init, collect, etc. commands, although they probably do not depend on all entries in args. However, if we want to only pass on the necessary arguments, we cannot call the sub-commands via args.func as we do currently, so we'd have to figure out how we want to do this instead.

@FlorianPommerening
Copy link
Contributor

I don't think this is a big problem. At some point we have to "unpack" the args and the place to unpack the values could be in the top-level function for each command. We could try do do it one level further outside (i.e., try to unpack the values before calling collect and then only passing the right arguments to collect) but that would just introduce a new level and then we could worry about how to get the unpacked values into that level.

Instead, I'd try to slim down the top level function. For example, don't implement all of the functionality in collect but split it up into smaller parts and extract those into methods. These inner/private methods then take the individual arguments. The top level function collect then only has the job of orchestrating the small parts and unpacking the args.

@FlorianPommerening
Copy link
Contributor

For example, collect is currently like this (comments removed for a shorter example)

def collect(_the_config: config.Config) -> None:
    sheet = sheets.Sheet(args.sheet_root_dir)
    collected_feedback_exists = any(
        (submission.get_collected_feedback_dir()).is_dir()
        and any((submission.get_collected_feedback_dir()).iterdir())
        for submission in sheet.get_relevant_submissions()
    )
    overwrite = None
    if collected_feedback_exists:
        overwrite = query_yes_no(
            (
                "There already exists collected feedback. Do you want to"
                " overwrite it?"
            ),
            default=False,
        )
        if overwrite:
            delete_collected_feedback_directories(sheet)
        else:
            logging.critical("Aborting 'collect' without overwriting existing collected feedback.")
    if args.xopp:
        export_xopp_files(sheet)
    create_collected_feedback_directories(sheet)
    for submission in sheet.get_relevant_submissions():
        collect_feedback_files(submission, _the_config, sheet)
    if _the_config.marking_mode == "exercise":
        create_share_archive(overwrite, sheet)
    if _the_config.use_marks_file:
        validate_marks_json(_the_config, sheet)
        print_marks(_the_config, sheet)
        create_individual_marks_file(_the_config, sheet)

It could become something like this

def collect(_the_config: config.Config, args) -> None:
    sheet = sheets.Sheet(args.sheet_root_dir)

    _collect_feedback(_the_config, sheet) # make private, include the overwrite check

    if args.xopp:
        _export_xopp_files(sheet) # make private
    if _the_config.marking_mode == "exercise":
        _create_share_archive(sheet) # make private, either do a separate overwrite check or delete everything with the first check
    if _the_config.use_marks_file:
        _create_individual_marks_file(_the_config, sheet) #make private, include validation, remove printing?

@FlorianPommerening
Copy link
Contributor

The additional layer could be useful, depending on how we want to split up the code though. The collect method in my previous comment clearly belongs to the implementation of the collect command. If we want to separate this from a dispatcher that doesn't know about the semantics of the commands an additional layer could be necessary. In that case, the problem is finding a good name for it. It could look something like this (maybe with a different name):

# Part of the general non-command-specific dispatcher code
def collect(config, args):
    sheet = Sheet(args.sheet_root_dir)
    commands.collect(config, sheet)

# In commands/collect.py
def collect(config, sheet):
    # Code from previous message

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants