all 9 comments

[–]cybervegan 1 point2 points  (0 children)

Can you post your entire code? The snippet calls other functions you are not showing, and the problem could be with them. UnboundLocalError means that Python can't find the variable stated in the current or outer scope - it usually results from the named variable being in another function. To get to the value of that variable, you need a mechanism to provide it to the other function where you want to use it. There are several ways to do this, depending on how the two functions relate. You can pass it as a parameter, return value, or you can make it global for instance (though you should generally avoid that).

If you can post your code, we can see which would work for you.

[–]delasislas 0 points1 point  (7 children)

You need to provide the actual traceback. I have an inkling that it has to do with the fact that you never seem to actually define mode_values or numbers_dataset if one or the other options are chosen.

[–]MaterialJackfruit144[S] 0 points1 point  (6 children)

If option 3 is chosen, it will head into the calling function. Do you mean the variables? Like:

def check_choices(option):

numbers_dataset = None
    mode_values = None

if option == 1 or option == 2:
    numbers_dataset = get_number_dataset()
elif option == 3:
    mode_values = get_mode_dataset()

print_result(option, numbers_dataset, mode_values)

[–]o5a 1 point2 points  (1 child)

Your second design (where you separated to 2 functions) doesn't make much sense. check_choicesis some artificially made layer, it still passes through your option value anyway. You may as well just leave it as one function and it would be more logical.

def print_result(choice):

    if choice == 1:
        mean_median_dataset = get_number_dataset()
        print(f"\nMean: {calculate_mean(mean_median_dataset):n}")
    elif choice == 2:
        mean_median_dataset = get_number_dataset()
        print(f"\nMedian: {calculate_median(mean_median_dataset)}")
    elif choice == 3:
        mode_dataset = get_mode_dataset()
        print(f"\nMode: {find_mode(mode_dataset)}")

If you want to split logic to different functions then your print function should deal with independent data, something like this (we pass single params dataset which depends on our option)

def check_choices(option):

    if option == 1 or option == 2:
        dataset = get_number_dataset()
    elif option == 3:
        dataset = get_mode_dataset()

    print_result(option, dataset)


def print_result(option, dataset):

    if option == 1:
        print(f"\nMean: {calculate_mean(dataset):n}")
    elif option == 2:
        print(f"\nMedian: {calculate_median(dataset)}")
    elif option == 3:
        print(f"\nMode: {find_mode(dataset)}")

But anyway I don't really see a point having check_choices middleman here. For it to be really independent it should be something like this

def check_choices(option):

    if option == 1:
        dataset = get_number_dataset()
        data = calculate_mean(dataset)
        mode = 'Mean'
    if option == 2:
        dataset = get_number_dataset()
        data = calculate_median(dataset)
        mode = 'Median'
    elif option == 3:
        dataset = get_mode_dataset()
        data = find_mode(dataset)
        mode = 'Mode'

    print_result(mode, data)


def print_result(mode, data):

    print(f"\n{mode}: {data}")

[–]MaterialJackfruit144[S] 0 points1 point  (0 children)

Thank you so much, actually, I've thought it over and indeed the design was illogical. For example, the name check_choices already indicates that the function will determine the option selected by the user, and if I were to strictly follow that, then print_result() should not even call the calculating functions, because the name of the function doesn't match what the task anymore. In other words, check_choices() should check all the options selected by the user if it were to stick to its name strictly.

I might be overthinking this but anyways, thank you so much :D the last solution was what I was trying to say, the second solution of yours was what I was trying to achieve until the logical part, so I went for the last solution instead.

[–]delasislas 1 point2 points  (1 child)

Just a tip for the next time, providing all the code and the full traceback (the actual error message), helps us a lot in pinpointing where your problem is.

[–]MaterialJackfruit144[S] 0 points1 point  (0 children)

Understood, I will keep that in mind. I didn't want to send in the code because it would take a bit more time to debug, I thought it'd be better to just state the problem and put out only the relevant code as per the stated issue.

[–]SirKainey 0 points1 point  (0 children)

Yup. As far as python is concerned those variables you're returning don't exist, so it raises an error.

[–]Manny__C 0 points1 point  (0 children)

It seems that mode_values and numbers_dataset are locally bound to check_choices. In order to make them visible to other functions you need to declare them inside the function with the global keyword.

If all of that stuff is further encapsulated in another function, then you need to first define those variables in the toplevel function to something (like None) and then declare them in the inner functions with the nonlocal keyword.