Pregunta

I am working on a currency converter for my computing GCSE at school and I have no idea what I am doing wrong here.

My code is:

PD = 1.66401 # declare pounds to dollars exchange rate

def Convert(ex): #converting sub... ex = exchange rate
    amount = input("Enter amount to convert: ") #get amount to convert
    result = round(float(amount) * float(ex),2) #calculate result using PD rate
    print("result = " + str(result)) #print result

def Change(ex): #change sub... ex = echange rate
    newex = input("Enter new exchange rate: ") #allow user to enter new exchange rate
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
        PD = float(newex) #change exchange rate

#display menu
menu = input("1.Convert\n2.Modify exchange rate\nPlease select option: ")
if menu == "1":
    Convert(PD) #Call sub...convert using pounds to dollars
elif menu == "2":
    Change(PD) #Call sub...change pounds to dollars exchange rate

When I convert it works correctly but when changing exchange rate i get the following error:

Traceback (most recent call last):
  File "F:/USB/Computing/Programming/Python/test2.py", line 18, in <module>
    Change(PD) #Call sub...change pounds to dollars echange rate
  File "F:/USB/Computing/Programming/Python/test2.py", line 10, in Change
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
UnboundLocalError: local variable 'PD' referenced before assignment

I have searched around but no answer has been very helpful if you could try and keep any explanations as simple as possible and provide an example of where Im going wrong and what i should be doing that would be greatly appreciated.

¿Fue útil?

Solución 3

You can access global variables just fine from inside functions. When you want to modify their values however, you need to first use global and declare them as being in the global scope:

def Change(ex):
    ##########
    global PD
    ##########
    newex = input("Enter new exchange rate: ")
    if ex == PD:
        PD = float(newex)

Otros consejos

def Change(ex): #change sub... ex = echange rate
    global PD
    newex = input("Enter new exchange rate: ") #allow user to enter new exchange rate
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
        PD = float(newex) #change exchange rate

More information in Python docs:

When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block’s environment.

If a name is bound in a block, it is a local variable of that block, unless declared as nonlocal. If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.

When a name is not found at all, a NameError exception is raised. If the name refers to a local variable that has not been bound, a UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.

This is a great example of where a class would be very helpful. By declaring PD as a class property, you can use the @property decorator to keep your code organized and not have to worry about global variables.

class CurrencyConverter(object):

    def __init__(self):
        """
        Set the default exchange rate to Pounds to U.S. Dollars
        """
        self.PD = 1.66401

    @property
    def PD(self):
        return self._PD

    @PD.setter
    def PD(self, value):
        """
        Set and ensure PD is a float value.
        """
        self._PD = float(value)

    def convert(self):
        """
        Takes user input and returns exchanged value.
        """
        amount = input("Enter amount to convert: ")
        result = round(float(amount) * self.PD, 2)
        print "result = %.2f\n" % result

    def change(self):
        """
        Takes user input and changes exchange rate.
        """
        newex = input("New exchange rate: ")
        self.PD = newex

The bonus with this method is that if your next assignment is to extend your currency converter, it'll be easy to add methods or inherit this class like so:

class CanadianExchangeRate(CurrencyConverter):
    """
    Converts Canadian Dollars to U.S. Dollars.
    """
    def __init__(self):
        self.PD = 0.90
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top