[Tutor] Looking for some comments on my code segment...

Dave (NK7Z) dave at nk7z.net
Fri Feb 24 16:13:10 EST 2023


Hi,

Many thanks for answering!!  I'll try and take each of your comments in 
order...

I tend to drop in with both feet into anything I try hence, the hello 
world to telnet move...

Tests to prove code:

The entire program is around 800 lines long at this point, and I did not 
want to drop that into an email...

An overview of what I am doing:
I have an amateur radio license, and there are telnet servers on the net 
called clusters, these clusters aggregate incoming spots, (little notes 
amateurs send to the cluster servers), to tell other amateur radio 
operators, they have seen a station, on such and such a frequency, using 
such and such a mode, at such and such a time.  The cluster spots are 
highly formatted, and are designed to be parsed by software.  This 
software is written for two reasons, one to teach me Python, and the 
other to alert me to selected stations from a list in a file, that 
changes from time to time.

The software logs into one of these clusters, parses the incoming telnet 
feed stream, and then verbally announces stations I am interested in, as 
defined in a separate file I populate.

Code Proof:
The code proof is that it is working, it logs into the clusters, and 
announces what I expect.  All the code works, as far as I can tell, the 
software logs in, IDs my by callsign to the server, configures the 
server stream, then looks at the incoming stream of data, and parses it 
looking at my want list from that other file.  A day can have as many as 
a million spots in it across a 24 hour period.


My question is motivated by the far end dropping telnet connection every 
few days, (reset server, update the server software, etc, does not 
happen often). I want to be able to trap that drop and gracefully leave 
the script.  Or perhaps relog in after I gain some confidence in my 
programming ability ion Python.

Globals:
I am using globals, because in some cases, the variable(s) I use is/are 
not passed to/from the function.

Where are these constants coming from:

They are defined very early on in the software.  I could drop thej 
software here, but it is around 800 lines long, so I decided to not as 
my first post...  :)

Failcode:
I write a log file of my own making, and add the fail codes in the event 
something dies, I know where...

Logging:
Not using logging library, I ran across that a few days ago, and will be 
switching to that method later, after things are running as I want.

exitscript:
Yes the main calling loop could leave with a try/except, but for now, I 
am exiting this way, that will guarantee a clean exit.  exitscript() is 
just a routine to kill things, in a way I KNOW will things get killed as 
  I want then to be killed.

Because I am interacting with someone else's server, and because this is 
the first telnet script in Python I have written, I want to INSURE 
without a doubt I have closed the connection in case of a fail of some 
sort in my code.

As I said, I am VERY new to Python...  I just learned how try/except 
worked a few weeks ago, so I did not put that in my main calling loop, I 
directed things to a function designed to kill things no matter what 
happened...  I am now using try/except and understand it, and at some 
point will correct things in the main caller.

There will be many changes to the script over time, right now I am 
working on the telnet portion, and that is why I am asking about that.

This entire script is a learning experience for me, and that is why I 
decided to write it in Python, never wrote in Python before, and for 
that I am sad...  Things seem to just come together in Python.  I am 
having a blast with it!

I can't seem to get my head around how to trap the telnet errors though...

Again, thanks for your help in all of this, and sorry the questions are 
so basic.

73, and thanks,
Dave (NK7Z)
https://www.nk7z.net
ARRL Volunteer Examiner
ARRL Technical Specialist, RFI
ARRL Asst. Director, NW Division, Technical Resources

On 2/24/23 12:14, dn via Tutor wrote:
> On 24/02/2023 16.14, Dave (NK7Z) wrote:
>> Hi,
>> New to Python programming, (this is part of my first Python program, 
>> beyond hello world), and I am working on some telnet stuff...
> 
> Welcome!
> 
> It is quite a BIG step to go from 'hello world' to simulating telnet! 
> However, picking a topic which 'floats your boat' is good motivation for 
> learning!
> 
> 
>> I would like to trap all errors, and think I am on to a start for 
>> this, but need a bit of help, too new to know what all I need to look 
>> for....
> 
> This seems to be more of a question about the protocol than Python.
> (and it's a somewhat specialised topic/little-corner of the PSL)
> 
> If you want to cover all the possibilities, then consider what each of 
> the calls to library-methods might return.
> 
> 
>> In the code below I am creating a telnet object for use later on in 
>> the program.  I believe I have it correct, but I am sure I have 
>> forgotten something.  It seems to run fine..
> 
> Which is as good a judgement as any other.
> 
> What tests are you using to prove the code?
> 
> 
>> Here is the function for that:
>>
>> def createtelnet():
>>      global tn, failcode
> 
> Why globals, cf passing these in as parameters/arguments and/or 
> return-ing the values?
> 
> 
>>      try:
>>          tn = telnetlib.Telnet(HOST, PORT, TIMEOUT)
> 
> (following-on from the above) where are these constants coming-from?
> 
> 
>>          logdata = "Telnet object created"
>>          logit(logdata)
> 
> Is "logdata" used later?
> If not, how about:
> 
>      logit( "Telnet object created" )
> 
> 
>>      except socket.timeout:  # Times out, exit with error.
>>          failcode = 1        # Let error handler know what is happening.
>>          logdata = 'Unable to create telnet object, timed out'
>>          logit(logdata)
>>          exitscript()        # Leave script.
>>
>>      except EOFError:
>>          logdata = 'Timeout reached in login.'
>>          logit(logdata)
>>          failcode = 10
>>          exitscript()        # Leave script.
> 
> What is the purpose/use of failcode?
> 
> 
>> All variables are set elsewhere, and the above code seems to work 
>> fine. What am I leaving out, or what don't I understand, looking for 
>> some comments on my code.
>>
>> Later on I am accessing the connection via:
>>
>>          try:
>>              result = tn.read_until(b"\r\n", TIMEOUT)     # Get a line.
>>              if result == 'b\'\'':
>>                  logdata = 'Stream has failed...'
>>                  logit(logdata)
>>                  failcode = 7
>>                  exitscript()  # Leave script.
>>
>>          except socket.error:          # If socket error-- exit.
>>              logdata = 'Socket Error in watchstream, at read.'
>>              logit(logdata)
>>              failcode = 8
>>              exitscript()  # Leave script.
>>
>>          except EOFError:         # If time out-- exit with error.
>>              failcode = 6  # Let error handler know what is happening.
>>              logdata = 'Timeout reached in watchstream'
>>              logit(logdata)
>>              exitscript()  # Leave script.
>>
>>          logdata = 'Telnet read succeeded, we got:\n' + str(result)
>>          logit(logdata)
>>          error = sys.stderr
>>          logit(str(error))
>>
>> Code to take apart the string follows this.  logit(), is a function to 
>> write a log as to what happened...
> 
> Good to see use of logging.
> (we are talking about the logging-library, aren't we?)
> 
> What is exitscript(), and what is its purpose?
> Could the calling routine wrap the call in its own try-except?
> 


More information about the Tutor mailing list