if statement for a subprocess python not working
Question: I've tried to create a little app that plays a sound when you lose
connectivity for an extended period and plays another when the connection is
established. Useful for wireless connections.

I'm still new to Python :) trying little projects to improve my knowledge. If
you do answer I will be very grateful if you could include any information
about how to use subprocess.

I've defined the subprocess but I'm not sure how to word my if statement so it
loops from one function to the other. IE Function 1 = IF ping loss > 15 pings
play sound and move on to function 2... If function 2 ping success > 15 pings
play sound and move back to function 1. So on.

I've yet to wrap the program in a loop, at this point I'm just trying to get
the ping to work with the if statement.

So right now the application just continuously loop pings.

    
    
    import os
    import subprocess
    import winsound
    import time
    
    def NetFail():
        winsound.Beep(2000 , 180), winsound.Beep(1400 , 180)
    
    def NetSucc():
        winsound.Beep(1400 , 250), winsound.Beep(2000 , 250),      
    
    ips=[]
    n = 1
    NetSuccess = 10
    NetFailure = 10
    PinSuc = 0
    PinFail = 0
    x = '8.8.8.8'
    
    ips.append(x)
    for ping in range(0,n):
    ipd=ips[ping]
    
    def PingFailure():
        while PinFail < NetSuccess:
            res = subprocess.call(['ping', '-n', '10', ipd])
        if ipd in str(res):
            PingSuccess()
        else:
            print ("ping to", ipd, "failed!"), NetFail()
    
    def PingSuccess():
        while PinFail < NetFailure: # This needs to be cleaned up so it doesn't interfere with the other function
            res = subprocess.call(['ping', '-n', '10', ipd])
        if ipd in str(res):
            PingFail()
        else:
            print ("ping to", ipd, "successful!"), NetSucc()
    


Answer: As you use the command `ping -n 10 ip`, I assume that you are using a Windows
system, as on Linux (or other Unix-like) it would be `ping -c 10 ip`.

Unfortunately, on Windows `ping` always return 0, so you cannot use the return
value to know whether peer was reached. And even the output is not very
clear...

So you should:

  * run in a `cmd` console the command `ping -n 1 ip` with an accessible and inaccessible ip, note the output and identify the differences. On my (french) system, it writes _Impossible_ , I suppose that you should get _Unable_ or the equivalent in your locale
  * start the `ping` from Python with `subprocess.Popen` redirecting the output to a pipe
  * get the output (and error output) from the command with `communicate`
  * search for the `Unable` word in output.

Code could be like:

    
    
    errWord = 'Unable'    # replace with what your locale defines...
    p = subprocess.Popen([ 'ping', '-n', '1', ipd],
                 stdout = subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
    if errWord in out:
        # process network disconnected
    else:
        # process network connected
    

Alternatively, you could search [pypi](https://pypi.python.org/) for a pure
Python implementation of ping such as py-ping ...

Anyway, I would not use two functions in flip-flop because it will be harder
if you later wanted to test connectivity to multiple IPs. I would rather use
an class

    
    
    class IP(object):
        UNABLE = "Unable"   # word indicating unreachable host
        MAX = 15            # number of success/failure to record new state
        def __init__(self, ip, failfunc, succfunc, initial = True):
            self.ip = ip
            self.failfunc = failfunc  # to warn of a disconnection
            self.succfunc = succfunc  # to warn of a connection
            self.connected = initial  # start by default in connected state
            self.curr = 0             # number of successive alternate states
        def test(self):
            p = subprocess.Popen([ 'ping', '-n', '1', self.ip],
                         stdout = subprocess.PIPE, stderr=subprocess.PIPE)
            out, err = p.communicate()
            if self.UNABLE in out:
                if self.connected:
                    self.curr += 1
                else:
                    self.curr = 0   # reset count
            else:
                if not self.connected:
                    self.curr += 1
                else:
                    self.curr = 0   # reset count
            if self.curr >= self.MAX:     # state has changed
                self.connected = not self.connected
                self.curr = 0
                if self.connected:        # warn for new state
                    self.succfunc(self)
                else:
                    self.failfunc(self)
    

Then you can iterate over a list of IP objects, repeatedly calling
`ip.test()`, and you will be warned for state changes

