user7362074
user7362074

Reputation:

Python variable error - reference before assignment

I have written a program that gets the information of a server. However, the program says that leng is referenced before assignment. How can I prevent this?

The program first scans for open ports. Then it connects to the first open port it finds. It then gets information about the server. The program then gets the IP address of the program and finally it closes the connection.

import socket

VER = None

portlist = [21,22,25,80,110,443]

ports_test = [21,22,25,80,110,443]

length = 0

leng = 0

siteORip = input("input either a site <eg:www.anysite.com> or an ip address<eg:123.45.67.890>>")

def get_ban():
    print("[CONNECTING>]Establishing connection...")
    while True:
        try:
            port = portlist.pop(0)
            s = socket.socket()
            socket.setdefaulttimeout(5)
            s.connect((siteORip,port))
            s.send("x".encode())
            data = s.recv(1024)
            print("[SERVER BANNER>]",data)
            break
        except:
            s.close()
            length = length + 1
            if length == 6:
                print("[ERROR>]Failed to connect")
                break
            else:
                continue

def get_info():
    try:
        info = socket.gethostbyaddr(siteORip)
        print("[SERVER INFO:([HOST,ADDITIONAL HOST,IP ADDRESS])>]",info)
    except:
        print("[ERROR>]Unknown error retrieving server info")

def get_ip():
    try:
        IP = socket.gethostbyname(siteORip)
    except:
        IP = socket.gethostbyname(siteORip)
    try:
        print("[IP ADDRESS>]",IP)
    except:
        print("[ERROR>]Unable to access IP")
    VER = 1
    s.close()

def ports_open():
    while True:
        try:
            for x in ports_test:
                s = socket.socket()
                socket.setdefaulttimeout(5)
                s.connect((siteORip,x))
                print("[TESTING...>]Port",x,"is open")
                s.close()
        except:
            print("[TESTING...>]Port",x,"is closed")
            s.close()
            leng = leng + 1
            if leng == 6:
                break
            else:
                continue

def main():
    ports_open()
    get_ban()
    get_info()
    get_ip()
    print("[<PROGRAM CONNECTION ENDED>]")

main()      
wait = input("")    

Upvotes: 0

Views: 43

Answers (1)

Tom Zych
Tom Zych

Reputation: 13576

Well, there are many problems with this code. The specific one you’re running into is the use of global variables being referenced locally. As a general rule, it’s better to pass data around between your functions explicitly, instead of having global data that might be changed anywhere.

Anyway … looking at the code as it is, you have the global variables leng and length defined and initialized at the top. Taking it in execution order, the function ports_open() tries to change the value of leng. It won’t succeed, but if it did, the function get_ban() would then try to change the value of length.

This fails, because (if I may be permitted to anthropomorphize) when Python sees these assignments, it thinks “Aha! A new local variable is being assigned! Oops, but its current value is being used, and it doesn’t have one. Error!”

We need to tell Python explicitly that we’re not using a local variable, but rather, the global variable. This is done by inserting lines like this before using the global:

global leng

global length

Do that, and this error will go away. There are other errors, but please try to fix them yourself, you’ll learn more that way.

Upvotes: 1

Related Questions