Search code examples
pythonfirebase-realtime-databaseraspberry-pirfid

Calling function from another Python file


I am trying to call a function from another Python file after a button is click. I have imported the file and used the FileName.fuctionName() to run the function. The problem is my exception keeps catching. I am guessing that the data from the function being called is not being grabbed.What I am trying to do is have a user fill out a Tkinter gui then click a button. Once the button is click the user will then be asked to scan their tag (rfid) and that data will then be sent to a firebase real time database which will store the user's inputted info along with the card_id and user_id that was created when the tag was scanned.

Im kinda at a loss because other than the exception catching I am not getting any other errors, any thoughts? I have posted the code below along with comments.

error : local variable 'user_id' referenced before assignment

from tkinter import *
#Second File
import Write
from tkcalendar import DateEntry
from firebase import firebase

data = {}

global user_id

# Firebase 
firebase= firebase.FirebaseApplication("https://xxxxxxx.firebaseio.com/",None)

# button click
def sub ():
    global user_id

    #setting Variables from user input
    name = entry_1.get()
    last = entry_2.get()
    number = phone.get()
 
    try:
        #Calling Function from other file
        Write.scan()
        if Write.scan():
            #getting the New User Id
            user_id= new_id

        
            #User Info being sent to the Database 
            data = {
            'Name #': name,
            'Last': last,
            'Number': number,
            'Card #':user_id
            }
        results = firebase.post('xxxxxxxx/User',data)
               
    except Exception as e:
        print(e)    

# setting main frame
root = Tk()
root.geometry('850x750')
root.title("Registration Form")

label_0 = Label(root, text="Registration form",width=20,font=("bold", 20))
label_0.place(x=280,y=10)

label_1 = Label(root, text="First Name",width=20,font=("bold", 10))
label_1.place(x=80,y=65)

entry_1 = Entry(root)
entry_1.place(x=240,y=65)

label_2 = Label(root, text="Last Name",width=20,font=("bold", 10))
label_2.place(x=68,y=95)

entry_2 = Entry(root)
entry_2.place(x=240,y=95)

phoneLabel = Label(root, text="Contact Number : ",width=20,font=("bold", 10))
phoneLabel.place(x=400,y=65)

phone = Entry(root)
phone.place(x=550,y=65)

Button(root, text='Submit',command = sub,width=20,bg='brown',fg='white').place(x=180,y=600)

root.mainloop()

Write.py file being Imported

import string
from random import*
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()

#Function being called
def scan():
    try:
        #Creating user hash
        c = string.digits + string.ascii_letters
        new_id = "".join(choice(c) for x in range(randint(25,25)))
        print("Please Scan tag")
    
        #Writing to tag
        reader.write(new_id)
        if reader.write(new_id):
            print("Tag Scanned")
        
        else:
            print("Scan Tag First")
        print("Scanning Complete")
    
    finally:
        GPIO.cleanup()

Solution

  • I see that the value new_id in one file isn't going to influence the value with the same name in the other file, for a similar reason as for the first problem. In both places it appears, new_id is a local variable that only exists in the enclosing function.

    Another issue I see is that you're calling Write.scan() twice in a row. Do you mean to be calling it twice? I expect not.

    Also, you're testing the return value of Write.scan(), but that function doesn't return a value. So I think that the code in the if block in the first file will never run.

    Globals are a bad idea in general, as they're easy to get wrong and they tend to obscure what the code is really doing. "Never say never", but I'll say that I very rarely find the need for a global variable in Python. In your case, I think it would be much better to have Write.scan() return the value of the new user id instead of passing it back as a global. Since you're testing the value of Write.scan(), maybe this is what you were thinking of doing already. Here are the changes I'd make to address these three issues and hopefully get your code working the way you want...

    ...
    
    def sub ():
        
        ...
        
        try:
            #Calling Function from other file
            new_id = Write.scan()
            if new_id:
                #getting the New User Id
                user_id= new_id
        
        ...
    
    ...
    
    def scan():
        try:
            
            ...
            
            new_id = "".join(choice(c) for x in range(randint(25,25)))
            
            ...
    
            return new_id
    
        finally:
            GPIO.cleanup()