spark
spark

Reputation: 19

Error message saying variable not defined when it is. Python

I am trying to create a simple encryption program in python using functions but am having a problem where I get an error message when I run the program saying ('msgReversed' is not defined) when it is.

the program works by first reversing the users message and then shifting the letters to the value of the Key

alphabet=("abcdefghijklmnopqrstuvwxyz ")

def userInput():
    plaintext=input("Enter message to encript")
    k=int(input("Enter encription Key you want to use (1-25)"))
    return (k,plaintext)

def reverseMsg(plaintext):
    msgReversed=''
    leng=len(plaintext)-1
    for c in plaintext:
        msgReversed+=plaintext[leng]
        leng=leng-1
    print(msgReversed)
    return(msgReversed)

def encript(msgReversed,k):
    cipher=''
    for c in msgReversed:
        if c in alphabet:
            cipher+=alphabet[(alphabet.index(c)+k)%(len(alphabet))]
        print(cipher)

(k,plaintext)=userInput()
reverseMsg(plaintext)
(cipher)=encript(msgReversed,k)

Error Message reads as follows`:

Line 26, in <module>
    (cipher)=encript(msgReversed,k)
NameError: name 'msgReversed' is not defined

Upvotes: 0

Views: 7665

Answers (4)

glls
glls

Reputation: 2403

As mentioned in my comment, your variable msgReversed is not declared outside of your function, so it is not defined when you call it outside of it. In order to avoid posting duplicate answers, here is another approach:

I do not know if you have worked with classes before, but here is an example and pythons official documentation (https://docs.python.org/2/tutorial/classes.html)

class Encrypt:

    def __init__(self):



        (k,plaintext)=self.userInput()
        self.reverseMsg(plaintext)
        cipher =self.encript(self.msgReversed,k)

    def userInput(self):
        plaintext=input("Enter message to encript")
        k=int(input("Enter encription Key you want to use (1-25)"))
        return (k,plaintext)

    def reverseMsg(self, plaintext):
        self.msgReversed=''
        leng=len(plaintext)-1
        for c in plaintext:
            self.msgReversed+=plaintext[leng]
            leng=leng-1
        print(self.msgReversed)
        return(self.msgReversed)

    def encript(slf, msgReversed, k):
        alphabet=("abcdefghijklmnopqrstuvwxyz ")
        cipher=''
        for c in msgReversed:
            if c in alphabet:
                cipher += alphabet[(alphabet.index(c)+k)%(len(alphabet))]
        print(cipher)

Encrypt()

As for Global variables, you can declare a global within a function. all you have to do is declare it global:

variable_name global

so your function with your variable msgReversed would be as follows:

def reverseMsg(plaintext):
    global msgReversed
    msgReversed = ''
    leng=len(plaintext)-1
    for c in plaintext:
        msgReversed+=plaintext[leng]
        leng=leng-1
    print(msgReversed)
    return(msgReversed)

Upvotes: 1

mfitzp
mfitzp

Reputation: 15545

When you return the msgReversed variable from the reverseMsg() function, you need to assign it to a new variable in the outside scope.

msgReversed = reverseMsg(plaintext)
(cipher)=encript(msgReversed,k)

I suspect the confusion arises with the following line:

return msgReversed  # Note, the brackets aren't required here

This returns from the function reverseMsg() while passing out the variable msgReversed. However, this variable isn't assigned anywhere by default — the name msgReversed is specific to the function. To store a value returned from a function you need to provide a variable name to store it in. Hence the following:

msgReversed = reverseMsg(plaintext)

...will store the value returned from your function in a new variable named msgReversed. You could also name that variable something else:

this_is_another_msgReversed = reverseMsg(plaintext)

If you don't provide a variable to assign the value to, it is simply lost:

reverseMsg(plaintext)
# No msgReversed variable here

Upvotes: 0

Fraans
Fraans

Reputation: 117

In your last line you pass a variable called 'msgReversed' into your 'encript' function. However: msgReversed is only locally defined inside your 'reverseMsg' function. Variables can either be local variables that only live inside of a function. Or global variables, that live in the entire script. A simple workaround would be to make your msgReversed a global variable, by simply adding 'global' in front of the first line of your 'reverseMsg' function. Another solution in your first to last line: msgReversed = reverseMsg(plaintext)

A simplified tutorial on this matter: http://www.python-course.eu/global_vs_local_variables.php

Added a simple example:

myname = "Marc"

def printName():
    myname = "Sonder"
    print (myname)

printName()
print (myname)

Outside of the function, the 'myname' function will yield "Marc". However inside the function, myname will yield "Sonder". If you would delete the first line, and try to execute the last line, to print the global version of 'myname', you will get the exact same error as you have got right now.

To grasp this I would copy this script, and see what changes when you comment certain parts out.

Upvotes: 0

Keatinge
Keatinge

Reputation: 4341

Change your last few lines from this:

reverseMsg(plaintext)
(cipher)=encript(msgReversed,k)

To this:

(cipher)=encript(reverseMsg(plaintext),k)

Upvotes: 0

Related Questions