Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 Rounding exercise: UnboundLocalError: local variable referenced before assignment
#1
This is for a personal challenge, not for school.

The task at hand:

Write a function which collects a list of floats as well as a boolean option. When the option is set to True, round up to the nearest full integer. However when the option is set to False, round down.

Here is my script that I came up with:
from math import ceil, floor

list_of_floats = [1.23, 4.32, 4.96, 16.10, 16.987]

rounded_list_of_floats = []

option = True


def round_up_or_down(list_of_floats, option):
    for individual_float in list_of_floats:
        if option == True:
            rounded_list_of_floats = rounded_list_of_floats + \
                ceil(individual_float)
        if option == False:
            rounded_list_of_floats = rounded_list_of_floats + \
                floor(individual_float)
        return rounded_list_of_floats


print(round_up_or_down(list_of_floats, False))
My interpreter runs this trace-back:
Quote:› python Bite153.py
Traceback (most recent call last):
File "Bite153.py", line 21, in <module>
print(round_up_or_down(list_of_floats, False))
File "Bite153.py", line 16, in round_up_or_down
rounded_list_of_floats = rounded_list_of_floats + \
UnboundLocalError: local variable 'rounded_list_of_floats' referenced before assignment

The problem is clearly with how I am referencing the rounded_list_of_floats variable.

So I Google 'UnboundLocalError' which turns up a doc by the UCSB titled:"Error: UnboundLocalError: local variable 'num' referenced before assignment". Based on my reading of this guide, I tried replacing line 13 with: rounded_list_of_floats += ceil(individual_float). No dice.

What kind of hints or advice could you people provide without giving me the solution entirely?

By the way, I originally got the idea to use the ceil() and floor() function from Real Python's guide called: How to Round Numbers in Python.
Quote
#2
(Feb-15-2020, 12:29 AM)Drone4four Wrote: What kind of hints or advice could you people provide without giving me the solution entirely?
OK. rounded_list_of_floats is an instance of builtin class list. You need to find appropriate method of list-class and use it instead of =/+=.
Quote
#3
A little bit simpler.
def round_up_or_down(list_of_floats, option):
    for individual_float in list_of_floats:
        if option:
            yield ceil(individual_float)
        else:
            yield floor(individual_float)


original_values = [1.5, 2.5, 3.5]
generator = round_up_or_down(original_values, True)
rounded_values = list(generator)
Your solution as normal function without implicit mutating a list on module level:
def round_up_or_down(list_of_floats, option):
    rounded_list_of_floats = []
    # never mutate implicit objects outside of the function
    # now rounded_list_of_floats inside the function is use for mutation
    for individual_float in list_of_floats:
        if option:
            rounded_list_of_floats.append(ceil(individual_float))
        else:
            rounded_list_of_floats.append(floor(individual_float))
    # pay attention for indentation. The return was before inside the for-block
    # which result into return from function after the first iteration of the for-loop.
    return rounded_list_of_floats
Your solution as normal function which mutates the list:
def round_up_or_down(list_of_floats, output, option):
    for individual_float in list_of_floats:
        if option:
            output.append(ceil(individual_float))
        else:
            output.append(floor(individual_float))


my_values = [1.5, 2.5, 3.5]
my_rounded_values = []  # it's a list
round_up_or_down(my_values, my_rounded_values, True)

print(my_rounded_values)
The cause why it's better to use scientific round is:
original_values = [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]
ceil_values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
scientific_round = list(map(round, original_values))

print('Sum of original values:', sum(original_values))
print('Sum of ceil values:', sum(ceil_values))
print('Sum of scientific rounded values:', sum(scientific_round))

print('Error between original and ceil values:', sum(ceil_values) - sum(original_values))
print('Error between original and scientific rounded values:', sum(scientific_round) - sum(original_values))
What you've learned in school is commercial rounding.
Scientific rounding ceil odd values at .5 and floor even values at .5.
It's defined in the IEEE 754
The function round in Python is using: to nearest, ties to even

You could have the control about rounding, if you use decimal.Decimal.
My code examples are always for Python >=3.6.0
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Quote
#4
Dear @DeaD_EyE: I appreciate the time and care you’ve invested in your reply to my original post. But you kinda ruined it for me because this was a personal challenge and you came up with 4 solutions that I wanted to do on my own. I specifically asked:

(Feb-15-2020, 12:29 AM)Drone4four Wrote: What kind of hints or advice could you people provide without giving me the solution entirely?

Thank you @scidam for your reply with your suggestion to explore list class methods. This is exactly what I needed to hear. I would have gone ahead and tried using the append or extend methods instead of =/+= but @DeaD_EyE already provided this solution. I’ll find a different exercise and make it more explicit next time here on this message board that I am not looking for solutions, just hints.
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Rounding without using Python embedded functions NewCoder 3 682 Sep-06-2018, 10:23 PM
Last Post: woooee
  UnboundLocalError: local variable 'a' referenced before assignment fad3r 3 11,223 Jun-20-2018, 05:43 PM
Last Post: nilamo
  why am I getting "local variable 'x' referenced before assignment"? wlsa 6 4,256 Jun-16-2018, 05:31 PM
Last Post: buran
  variable referenced before assignment Niko047 4 14,253 Aug-04-2017, 07:55 PM
Last Post: nilamo
  local variable 'l' referenced before assignment... darkreaper1959 4 4,013 Jan-21-2017, 08:16 PM
Last Post: Larz60+

Forum Jump:


Users browsing this thread: 1 Guest(s)