Trying to get into good code habbits

Trying to get into good code habbits

Author
Discussion

grumbledoak

31,545 posts

234 months

Tuesday 24th March 2015
quotequote all
gottans said:
I think comments are valuable but have to provide useful information, not sticking any comments is is a typical tactic of a contract software coder, then make it look very complicated and unintelligible so they extend your contract.
In my experience 'permanent' and 'contract' are just words. Plenty of very average people are doing it only for the money. And these people can make anything seem complicated. They are the same bunch that whine whenever Microsoft makes the OS easier to use. They simply don't "get it".


And, OP, if you name your variables correctly you don't need comments

start_time = time.clock()
port_scan(low_port, high_port)
end_time = time.clock()

print("\nScan completed in ", end_time - start_time, " seconds")



Edited by grumbledoak on Tuesday 24th March 20:45

Tonsko

6,299 posts

216 months

Tuesday 24th March 2015
quotequote all
Interesting. I'm not sure why you would be using wget? That's more for downloading things. You'd be better off using 'ping'. I've only started python myself recently, and on my first script I wrote a firewall scanner with hping. Hping is more controllable than ping, as ping only uses ICMP 13, which some network boundary devices are configured to ignore. With hping you can design the packets that you send to the target, so you can send a connect packet using TCP instead of ICMP. The latest version of hping is hping3.

Some other areas to look at: sockets and argparse.

Argparse is great - it forces you to use switches on the command line, and provides help to the user if asked for (examples on how to use it). sockets are useful to address. It basically parses (who'd'a'thunk!) the command line arguments.

Socket for addressing sockets, a low-level networking feature. This sounds scarier than it is.

If you want to dive right in to low level network addressing, check out scapy - a really powerful feature-rich module that has all the control that you may want. I'm just starting to look at it now.

CountZero23

1,288 posts

179 months

Tuesday 24th March 2015
quotequote all
grumbledoak said:
And, OP, if you name your variables correctly you don't need comments

start_time = time.clock()
port_scan(low_port, high_port)
end_time = time.clock()

print("\nScan completed in ", end_time - start_time, " seconds")
Yup, and extracting code into well named methods. Comments really should be the exception not the rule.

Free years ago it was the fashion to comment EVERYTHING in the Microsoft world. Spent half my time removing redundant comments from legacy code.




SystemParanoia

Original Poster:

14,343 posts

199 months

Tuesday 24th March 2015
quotequote all
I have taken this onboard.
I thought I was being clever getting it on one line. but your points are clear and concise. sometimes the extra line is worth it as it makes things so much clearer.

Tonsko,

I used wget as I have marginally more experience with it than netcat or curl having recently performed my first arch install.

I'll read up on that scappy module, but I feel ill be needing to get rather intimate with curl, and the requests python module in the not-to-distant future hehe


Tonsko

6,299 posts

216 months

Tuesday 24th March 2015
quotequote all
Probably best to avoid scapy for now! Keep it in the back bin for later smile

But definitely investigate hping3. It's designed for exactly what you're trying to do here (check for open ports). Curl is similar to wget. Netcat is ok though.

Edited by Tonsko on Tuesday 24th March 21:19

sparkyhx

4,152 posts

205 months

Tuesday 24th March 2015
quotequote all
onomatopoeia said:
sparkyhx said:
Possibly a contentious point, but 30 years experience has taught me this.

Our Assembler programmers used to write code like the above - every line was annotated. I could look at the code and debug it without even knowing the language. Also amend it as there were enough comments to work out what it was doing and work out how to amend it.
My assembly language code is full of comments / annotations, but always explaining "why", not "what".

Some things get explained a lot, like the format of the stack on entry to a function, what it needs to be on exit and which registers survive calls into the operating system, so if someone unfamiliar with the platform needs to do something with it they don't immediately fall over because they write code the causes a register or the stack to be unexpectedly splatted, with the usual consequences.
Our guys got 2 years on the job training. Yes there were good and bad, but the bad often got weeded out simply by needing to write code in a structured organised and controlled way.

Todays languages/apps etc are less rigid and I don't think everyone is 'trained' how to be a programmer first and then trained in languages second. hey ho - more work for me :-)

eharding

13,740 posts

285 months

Tuesday 24th March 2015
quotequote all
SystemParanoia said:
I have taken this onboard.
I thought I was being clever getting it on one line. but your points are clear and concise. sometimes the extra line is worth it as it makes things so much clearer.

Tonsko,

I used wget as I have marginally more experience with it than netcat or curl having recently performed my first arch install.

I'll read up on that scappy module, but I feel ill be needing to get rather intimate with curl, and the requests python module in the not-to-distant future hehe
'requests' is your friend, you may not know it yet, but worth getting to know...but not for a port scanner. You need to be rocking at the socket level for that.

The indentation in your last sample was rather wonky - uniform enough to keep the interpreter happy, but a bit suspect.

If you want to avoid much wailing and gnashing of teeth, start putting your code under some form of version control - Git....isn't an insult, just a suggestion. Very popular with the younger generation - I started out using SCCS back in the day, went through RCS, CVS, the WebDAV DeltaV thing we built that pre-dated Subversion, and am still happy with Subversion for my personal and our corporate requirements: plenty of free hosted solutions - Unfuddle or Github for example. Use one. Think of it as a software development prophylactic - young, wild and free using one might seem like a hinderance, but you'll regret not doing so when your knob drops off, Pythonically speaking, and you can't remember what the version of your knob that hadn't dropped off looked like.



SystemParanoia

Original Poster:

14,343 posts

199 months

Tuesday 24th March 2015
quotequote all
yeah, I cant seem to get the indents to behave on this forum.

I do my editing in geany and just cut/paste, and the forum makes it rather "wonky"


eharding

13,740 posts

285 months

Tuesday 24th March 2015
quotequote all
SystemParanoia said:
yeah, I cant seem to get the indents to behave on this forum.

I do my editing in geany and just cut/paste, and the forum makes it rather "wonky"
Just be *very* sure you aren't using any <tab> characters in the code. Spaces only. Don't take any crap from the <tab> fan-brigade muppets on this. Pick a space-character indentation, and stick with it. Opinions vary, but 2 keeps the code concise. 3 is just...odd, and four is simply profligate. Conversely, a single character indent smacks of just being lazy.

Edited: you haven't pointed us to the Github (other hosted SCM solutions are available) URL where we can fork your code, fix it, and you can merge our code-meister-deity changes back. As per the previous post. Do it.











Edited by eharding on Tuesday 24th March 22:13

SystemParanoia

Original Poster:

14,343 posts

199 months

Tuesday 24th March 2015
quotequote all
*clicks furiously*


hehe

Tonsko

6,299 posts

216 months

Tuesday 24th March 2015
quotequote all
Do you really recommend github for even small projects? Not really thought about it for little scripts... then again, I do lose track of the script how it 'used to be'.

Edited by Tonsko on Tuesday 24th March 22:34

eharding

13,740 posts

285 months

Tuesday 24th March 2015
quotequote all
SystemParanoia][NOWIKI said:
hehe
....and you might want to look as publishing your code examples as IPython (now Jupyter) notebooks at some stage - this is where the whole dynamic nature of Python (and the other language kernels supported by IPython/Jupyter) just blows the old compiled languages out of the water - they're not going away, but they're not going anywhere new either.


SystemParanoia

Original Poster:

14,343 posts

199 months

Tuesday 24th March 2015
quotequote all
ive created an account

https://github.com/systemparanoia/dried-fruit

but, it looks like im going to need time to figure this out lol.

ive only ever git-cloned stuff before, and not always successfully haha smile

eharding

13,740 posts

285 months

Tuesday 24th March 2015
quotequote all
Tonsko said:
Do you really recommend github for even small projects? Not really thought about it for little scripts... then again, I do lose track of the script how it 'used to be'.

Edited by Tonsko on Tuesday 24th March 22:34
I think you've answered your own question. hehe

Hosted SCM tools are so freely available now that, if you don't have your own repository, you'd be mad not to use one.



eharding

13,740 posts

285 months

Tuesday 24th March 2015
quotequote all
SystemParanoia said:
ive created an account

https://github.com/systemparanoia/dried-fruit

but, it looks like im going to need time to figure this out lol.

ive only ever git-cloned stuff before, and not always successfully haha smile
Stick with it. You'll work it out.

cornet

1,469 posts

159 months

Tuesday 24th March 2015
quotequote all
If nothing else from this thread I'm learning some python (I'm not a developer, I'm a sysadmin that knows enough Ruby to cause trouble).

Anyway I decided again to try and get the OP's code working and (IMHO) clean it up a bit.

The only major thing I've changed is to use subprocess.call rather than firing off child process and having to poll it which I'll admit is a step backward and I might look at using subprocess.Popen when I figure out a neat way to handle it.

Also I'm going on the premise here that wget will return non-zero if there it is blocked (I firewalled off a port to test and got return code 4 which is "Network Error" according to the man page).

Kudos to the OP as well for writing the code - great effort for your first steps into programming smile

Anyhoo - here goes:


#!/usr/bin/env python3

import subprocess
import os
import time

def port_open(port):
"""
Checks status of a port
Returns true if open, false if closed
"""
WEBSITE = "portquiz.net"
url = WEBSITE + ":%d" % port
return_code = subprocess.call(["wget", '-qO -', url])

return True if return_code == 0 else False


def port_scan(low_port, high_port):
"""
Scans a all ports between low_port and high_port.
Returns a dict with the results indexed by port number.
"""
results = () # Again curl braces here thanks to PH not being able to cope
for port in range(low_port, high_port):
results[port] = port_open(port)
return results


def output(results):
"""
Outputs status off all ports in the results dict.
"""
for port in results:
status = "open" if results[port] else "closed"
print("Port %d is %s" % (port, status))


def yes_response(resp):
YES_RESPONSES = ["y", "yes"]
return True if resp.lower() in YES_RESPONSES else False


def main():
while True:
try:
low_port = int(input("Enter low port: "))
high_port = int(input("Enter high port: "))
except ValueError:
print("\nPlease enter numbers and not letters")
continue

if low_port > high_port:
print("\nLow port must be greater than high port")
continue

start_time = time.clock()
results = port_scan(low_port, high_port)
end_time = time.clock()

print ("\nScan completed in %f seconds" % (end_time - start_time))

output(results)

if not yes_response(input("\nDo you wish to perform another scan? Y/N : ")):
break

if __name__ == "__main__":
try:
main()
# If user hits Ctrl+C or similar then exit cleanly
except KeyboardInterrupt:
print("\nShutdown requested... exiting\n\n")
os._exit(0)


Edited by cornet on Tuesday 24th March 23:03

Goaty Bill 2

3,415 posts

120 months

Wednesday 25th March 2015
quotequote all
eharding said:
Just be *very* sure you aren't using any <tab> characters in the code. Spaces only. Don't take any crap from the <tab> fan-brigade muppets on this. Pick a space-character indentation, and stick with it. Opinions vary, but 2 keeps the code concise. 3 is just...odd, and four is simply profligate. Conversely, a single character indent smacks of just being lazy.
Amen to that piece of advice.
The times I have started by saying, as politely as possible; 'tabs in code should be a sackable offence' and received a blank stare in return, and then clarify; 'There will be no tabs in your code. Got it?'. 'There will be two indents, not one, not three; Got it?'

I then seem to find that further explanation is required along the lines of;
I don't tell you what editor to use, I want you to be as comfortable and productive as possible for all of our sakes (yes even yours). But just because you choose to use some crutch of a database query tool, because you have forgotten (if indeed ever learned) the data dictionary, with an editor with less functionality than notepad doesn't mean everyone else here is similarly disabled, or that their choice of editor will 'understand' tabs the same way yours does.


In extreme cases, for the severely incapable, I have had people use code formatters to run over their code prior to saving to source control.


grumbledoak said:
In my experience 'permanent' and 'contract' are just words. Plenty of very average people are doing it only for the money. And these people can make anything seem complicated. They are the same bunch that whine whenever Microsoft makes the OS easier to use. They simply don't "get it".
I agree wholeheartedly there.
Myself and a few others that I have had the pleasure of working with on a number of occasions, insist on sufficiently clear and concise documentation and commenting to allow virtually anyone to pick up our work should we leave/die/retire or the code is picked up for enhancement later.

In my experience, a contractor is rarely called back because no one could read their code.
Then the 'new guy/gal' has all the excuses in the world to criticise, demean and trash your work while extending their contact with the inevitable re-write; because no one could understand what was there.

To me that of all things is a failure.


grumbledoak said:
And, OP, if you name your variables correctlywell you don't need comments
Sorry, couldn't resist smile
Again much in agreement, as others have indicated similarly.

Generally, following good practice, all procedures and functions will be quite short.
One hundred lines or less. In an ideal world, the majority might be as short as what can be seen on the screen. This nullifies the requirement for extensive commenting.
This isn't always possible of course. For example; assigning all the variables in a SQL update statement for a table with 250 columns.

But in either case, often the only comment that is required then; describes the method's purpose.


Sometimes, there might be a requirement for describing pre-conditions, and it is not uncommon, especially when writing utility code (libraries to be re-used by others, or many times is disparate places), to fully document the parameters and exceptions/messages.
Javadoc is an example of this as a formal methodology.
It is usual, in my experience then, to document all public methods to the fullest extent; i.e. purpose of the method, any pre-requisites, each parameter, valid parameter values, expected exceptions, expected output/results.

This is, after all, what we expect of published libraries that we make use of.



SystemParanoia

Original Poster:

14,343 posts

199 months

Wednesday 25th March 2015
quotequote all
That above re-interpretation is alot clearer.
thank you smile

Im endlessly thinking of stuff to try and attempt.
really enjoying the programming experience so-far, I absolutely wish I had started sooner smile

turns out almost all outbound ports are blocked on the works wifi. The only open ports i found were 25, 80, 443, and 1723
so I just adjusted the port forwarding on my home firewall to reflect this and now ssh is working again. hurrah for python! smile

just hope I dont fall into this XKCD trap though


TheExcession

11,669 posts

251 months

Wednesday 25th March 2015
quotequote all
A very interesting thread, I see the complexity growing a little and the learning curve steepening, we should remember 'good coding habbits' are about understanding the problem and being able to describe and solve that problem elegantly and with the fewest key-presses (lines of code).

Good coding is not about writing comments, good coding is about understanding the questions and providing answers.

I'm not a Python programmer (would someone explain why Python syntax/structure is better than Java for example), but a quick Google indicates that the language does support a class based architecture.

We have got the commenting of code sorted and the presentation in terms of using tabs or 2 spaces is behind us, now might be a good time to think about the tasks a program is asked to perform and start pushing those tasks out to dedicated portions of code (classes).

Returning to the initial set of requirements from the OP which was to calculate the area of a triangle.

Would one of the people following this thread like to try and break (hehe) down the functions and answer a whole load more ?

I'll run with the OP example "Area of a triangle" and see if the new coders here that want to learn can also answer these questions?

  • Is it a right angled triangle?
  • What's the SIN or COS of the angle at A`, at B` or C`?
So now we need to build a triangle 'class' that understands everything about a triangle, it needs a few inputs, A,B,C in a coordinate fashion, after that is should be able to answer every question about this triangle.

What it should NOT do is 'print' or 'printf'.

As an onlooker on this thread I'd be delighted to see 'the learners' (that's what we have to call them these days) get a grip and really understand what they are trying to achieve.






grumbledoak

31,545 posts

234 months

Wednesday 25th March 2015
quotequote all
TheExcession said:
A very interesting thread, I see the complexity growing a little and the learning curve steepening, we should remember 'good coding habbits' are about understanding the problem and being able to describe and solve that problem elegantly and with the fewest key-presses (lines of code).
I disagree. An elegant solution is pleasing to the developer but not necessary or always possible. Fewest key-presses or lines of code as a measure of quality is laughable.

TheExcession said:
So now we need to build a triangle 'class' that understands everything about a triangle, it needs a few inputs, A,B,C in a coordinate fashion, after that is should be able to answer every question about this triangle.

What it should NOT do is 'print' or 'printf'.

As an onlooker on this thread I'd be delighted to see 'the learners' (that's what we have to call them these days) get a grip and really understand what they are trying to achieve.
Again, I disagree. You demonstrate one of the problems of OO code as so often done. You want a banana. You get a banana, held by a gorilla, in a jungle. The banana can be any RGB colour you want.

Clear and bug free are good first aims. OP is getting there.


Edited by grumbledoak on Wednesday 25th March 21:36