Trying to get into good code habbits

Trying to get into good code habbits

Author
Discussion

TheExcession

11,669 posts

250 months

Wednesday 18th March 2015
quotequote all
So meanwhile whilst we've all been rabbiting on.....
SystemParanoia said:
This thread has turned out to be an absolute gold mine!! Thanks guys.

Today I have mostly been writing task automation scripts to use on the works computer using sikuli.

Group policy on the active directory works machines is pretty tightly locked down. No bat/exe/MSI executions allowed without admin.. Java is completely unrestricted however. Meaning I could install the sikuli java/python environment
LEARN JAVA; NO LEARN PHP, C++ IS WHERE IT IS AT, AWWW CRAP JUST LEARN MICROSOFT...
hehe

Goaty Bill 2

3,407 posts

119 months

Thursday 19th March 2015
quotequote all
@grumbledoak
Just in case my intent is lost; I only wish to reply to your statements, not start a bun fight smile
I am as open to your opinions, clearly also based upon long experience, as I am to others.

grumbledoak said:
...
It won't surprise you then, that C# is what Java would have been if it had been done by people who knew what they were doing.
Actually it would surprise me; given MS has only ever (and from a business perspective, probably should only ever) have been interested MS centric solutions.
But again, without knowledge of c#, I can't really comment.

And you probably perfectly correct in saying 'the choice between C# and Java is more religious than technical.', given that as you and others have stated variously on their similarities, and that after all, once the principals are learned well, changing languages for a purpose is relatively easy.

For me personally, it's a moot point in any case.
I work exclusively with Oracle RDBMS focused technology, and that is deployed across a number of operating systems. Currently only Java supplies the means to interface with every operating system that Oracle is deployed to, so when I need such a facility; it will have to be Java.

grumbledoak said:
Java is probably the next Cobol if you are job-for-life minded.
You can ignore C++ - it's just an unpleasant chapter in the history books now.
smile
Reminds me of a small seminar 18 years ago, when a visiting Oracle dignitary told our gathered technical consultants that Oracle would soon be 300% Java (RDBMS, Middle Tier, UI). PL/SQL is dead.
I was most distressed given the countless hours of studying, thousands of lines of practice code, test after test to learn all the features.
Eighteen years and hundreds of thousands of code lines since; I haven't stopped designing and writing PL/SQL.

But eventually; all things pass.

dcb said:
grumbledoak said:
And I wouldn't bother with the "Gang of Four" Design Patterns book right now - it's no use to a beginner.
Now that I can agree with.
As would I, whole heartedly. But I did prefix; 'If you one day make the foray into the OOP world of Java, C++ or their ilk...'
My (recommended purchase) copy sat on the shelf for a good 3-4 years before I began to read it.


SystemParanoia

Original Poster:

14,343 posts

198 months

Thursday 19th March 2015
quotequote all
cornet said:
This appears to have gone off topic somewhat. So bringing this back on track and playing some code golf to try and help the OP.

I've done very little python so their might not be some common idioms I'm using but here goes.

The goals when writing this were:

  • Make sure functions have a clear purpose and are reusable
  • Catch errors as early as possible in the program
  • Keep logic separate from presentation


#!/usr/bin/env python

def calc_area(base, height):
"""Calculate and return the area of a triangle give the base and height"""
return base * height / 2


def yes_response(resp):
"""Check if string is a yes response and return true if so"""
YES_RESPONSES = ["y", "yes"]

resp = resp.lower()

if resp in YES_RESPONSES:
return True
else:
return False


def main():
while True:
print "\nThis programme calculates the area of a triangle\n"

try:
base = float(raw_input("Enter Base Value: "))
height = float(raw_input("Enter Height value: "))
except ValueError:
print "\nPlease enter numbers and not letters"
continue # Skips to next iteration of the loop

area = calc_area(base, height)

print "The working out is, %d x %d / 2" % (base, height)
print "Base x height =", base * height
print "Once divided by 2 the area of your triangle is", area

if not yes_response(raw_input("\nDo you wish to continue? Y/N ")):
break # Exits the loop

print "\nGood Bye\n"


if __name__=="__main__":
main()
that is exactly what i meant to write!!

Thank you for this, it didn't even occur to me even consider having the calculation within the return statement and catching the exception of the float immediately at input instead of taking a raw string and converting it later et al, and all the other stuff you did to minimise the lines of code required.

elegant smile


Edited by SystemParanoia on Thursday 19th March 15:14

cornet

1,469 posts

158 months

Thursday 19th March 2015
quotequote all
SystemParanoia said:
that is exactly what i meant to write!!

Thank you for this, it didn't even occur to me think to have the calculation within the return statement and a whole heap of other stuff you did to minimise the lines of code required.

brilliant smile
Glad it was helpful, I'd probably shorten the yes response function slightly looking at it again.



def yes_response(resp):
"""Check if string is a yes response and return true if so"""
YES_RESPONSES = ["y", "yes"]

if resp.lower() in YES_RESPONSES:
return True
else:
return False

grumbledoak

31,532 posts

233 months

Thursday 19th March 2015
quotequote all
cornet said:
Glad it was helpful, I'd probably shorten the yes response function slightly looking at it again.
It would be clearer if you inlined that function so the "return True" becomes the "break". Minor stuff; it's all a lot clearer than in started. thumbup

dcb

5,834 posts

265 months

Thursday 19th March 2015
quotequote all
ATG said:
It (Python) is one of the key strategic languages used by my employer and several of our major competitors building major in house systems.
Really ? That's a surprise.

While million line C / C++ / Fortran programs are common, I had
no idea interpreted languages like Python and Perl had reached a
similar level.

The biggest Python or Perl program I've ever worked on
was about 3K lines of code ;->

So it is presumably the case that there are 10K or maybe 100K line
Perl and Python programs out there.

How does performance compare on such large programs ?

dcb

5,834 posts

265 months

Thursday 19th March 2015
quotequote all
ATG said:
It (Python) is one of the key strategic languages used by my employer and several of our major competitors building major in house systems.
Really ? That's a surprise.

While million line C / C++ / Fortran programs are common, I had
no idea interpreted languages like Python and Perl had reached a
similar level.

The biggest Python or Perl program I've ever worked on
was about 3K lines of code ;->

So it is presumably the case that there are 10K or maybe 100K line
Perl and Python programs out there.

How does performance compare on such large programs ?

Tonsko

6,299 posts

215 months

Thursday 19th March 2015
quotequote all
Large chunks of Eve Online code is python.

cornet

1,469 posts

158 months

Thursday 19th March 2015
quotequote all
dcb said:
Really ? That's a surprise.

While million line C / C++ / Fortran programs are common, I had
no idea interpreted languages like Python and Perl had reached a
similar level.

The biggest Python or Perl program I've ever worked on
was about 3K lines of code ;->

So it is presumably the case that there are 10K or maybe 100K line
Perl and Python programs out there.

How does performance compare on such large programs ?
It's not really surprising, there are plenty of applications where you don't need the raw speed of C. With computers getting more powerful and higher level programming languages being more efficient in terms of developer time then it makes perfect sense.

Also while lines of code isn't a metric you should be using to judge anything there are plenty of large python projects: eg. https://www.openhub.net/p/django @ 400k+ lines of code (and that probably isn't including 3rd party libraries it pulls in)


As for performance then it all depends on where your bottlenecks are going to be. For many applications it's more than fast enough. With web applications for example often the CPU isn't the bottleneck with respect to performance.

grumbledoak

31,532 posts

233 months

Thursday 19th March 2015
quotequote all
cornet said:
... raw speed of C.
That grinds my gears. The presumption that C is quick because it is so low level. Just because you can see the assembly that will be produced is no guarantee of speed. Most C programs spend much of their time in strlen() because the 'designers' couldn't be arsed writing a proper string type. In the real world correct algorithm selection is the best way to speed, and you can do that with any language.

And I've dragged us off topic again...

scorp

8,783 posts

229 months

Friday 20th March 2015
quotequote all
grumbledoak said:
cornet said:
... raw speed of C.
That grinds my gears. The presumption that C is quick because it is so low level. Just because you can see the assembly that will be produced is no guarantee of speed. Most C programs spend much of their time in strlen() because the 'designers' couldn't be arsed writing a proper string type. In the real world correct algorithm selection is the best way to speed, and you can do that with any language.

And I've dragged us off topic again...
C is deceptively easy to learn, but hard to master I would say.


Tonsko

6,299 posts

215 months

Monday 23rd March 2015
quotequote all
OP, I gave some of my python code to a more experienced developer the other day, and he pointed me towards pep8. Pep8 is a style guide for python, and (ostensibly) is an effort to standardise writing python. It turned out that I was using a few of them anyway, but a few I wasn't, such as putting each import on a separate line, breaking long commands down into 79 character lengths etc.

It has quite a few interesting bits and pieces, and you should check it out (but you don't have to use them obvs, but in-line with the topic, I thought it might be helpful): https://www.python.org/dev/peps/pep-0008/

sparkyhx

4,151 posts

204 months

Monday 23rd March 2015
quotequote all
SystemParanoia said:
Hey guys,

Im currently filling my spare time messing around with python and learning how to use it blah blah blah.

Ive created a couple quick a dirty programs to get me used to the new syntax im learning and when best to use it.

ill paste my code below.

Its a simple program to calculate the area of a triangle. with pretty basic error checking.

if any of you have suggestions on making it more elegant or "pythonic" as they say; i'd love to hear it smile

I appreciate that im probably on completely the wrong website for receiving feedback on this sort of thing, but signing up for new webforums all the time is alot of effort!



#! /usr/bin/env python

#
#
#========= ( EXPLANATION OF FIRST LINE )=========#
#
#

'''
If you have several versions of Python installed, /usr/bin/env will
ensure the interpreter used is the first one on your environment's
$PATH. The alternative would be to hardcode something line
#!/usr/bin/python or the like -- that's OK but less flexible.

In Unix / Linux, an executable file that's meant to be interpreted can
indicate what interpreter to use by having a #! at the start of the
first line, followed by the interpreter (and any flags it may need).

With other platforms like Windows, of course, this rule does not
apply (but that "shebang line" does no harm, and will help if you ever
copy that script to a platform with a Unix base, such as Linux or Mac.
'''

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#
#
#========= ( SYSTEMPARANOIAS INTRODUCTION NOTES )=========#
#
#

'''
Program created by SYSTEMPARANOIA 3/2015
Final revision and most robust version of python calculator that not
only works out the area of a triangle using the base x height divided
by 2 method.
It also has an Error Checking function on the user input to make sure
the user is entering a number and not a letter and forces the program
to run again if an error is found.
I have also added a continuation function to allow the programme to exit
cleanly when the user is ready.
This version is set within a (while) loop using multiple
definitions (def) that can be called repeatedly in this and other
programs.
This version gives the workings out for the user and exits cleanly.
'''

#
#
#========= ( DEFINITIONS OF FUNCTIONS )=========#
#
#

'''
This function performs the main calculations for the program and
prints the results on screen including the workings out for the sum.

To explain the first print statement, see sample code below:

name = 'maths'
number = 42
print '%s %d' % (name, number)

will print maths 42.

Note that name is a string (%s) and
number is an integer (%d for decimal)

'''

def triangle(base, height): # Name of the function with arguments
base = float(base) # Convert Variable to decimal
height = float(height) # Convert Variable to decimal
area = base * height / 2 # Perform calculation
print "The working out is, %d x %d / 2" % (base, height)
print "Base x height =", base * height
print "Once divided by 2 the area of your triangle is ",area

'''
This Function performs a check of the user's input to make sure
that it is a number and will not cause the program to crash due to
the user entering a string.
'''

def is_number(n): #Name of the function with argument
try: #Attempt the following action
float(n) #Convert to float with argument
return True #If successful return True
except ValueError: #Check if error message is received
return False #If Error, return False

'''
This function performs a check if the user would like to continue
and run another calculation, or to end the program. it returns a true
or a false value.
'''

def re_run(c): #Name of Function with argument
c.lower() #Force string to Lower case
if c == "y" or c == "yes": #If one of these values are True then..
return True #End function with True value
else: #If both are False then..
print "\nGood Bye\n" #Print String
return False #End function with False value

#
#
#========= ( DEFINITIONS OF VARIABLES )=========#
#
#

'''
This variable is what the while loop checks to see if it should
loop again or not. Once set, a variable can be changed to any other
value at any time
'''

i = True #Set variable to True

#
#
#========= ( DEFINITIONS OF PROGRAM LOOPS )=========#
#
#

# Start of loop, check if 'i' is true, otherwise do not loop
while i == True:
print "\nThis programme calculates the area of a triangle\n"
base = raw_input("Enter Base Value: ")
height = raw_input("Enter Height value: ")
# Call function and check if both results return a True value
if is_number(base) and is_number(height):

# Print contents of triangle function
print triangle(base, height)

#If error or exception
else:
print "\nPlease enter numbers and not letters"

# Call continue function to change variable to true or false
# This will change the value of the variable 'i' above to either True
# or False.

i = re_run(raw_input("\nDo you wish to continue? Y/N "))



'''
This version that will work with decimals, and wont break with letters
it will also loop over and over to allow for repeated use until
the user decides to quit.

This version has Error Checking and is very robust.
These definitions can be taken and used in other programmes the user
may create

Notice that the main programme is only 10 lines of code. if you want to
change how it works, you do not have to change much. The previous
versions of the program would need a complete re-write.
'''


very 'old school' approach from the era where programmers did a good job.....................In my opinion most of todays programmers are crap, they write crap code and throw it over the wall pretty much untested. However possibly a bit over the top.

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.

I sometimes wish I could annotate Excel formulas. I don't do complex ones enough to remember how they work. It would be nice to have a helping hand sometimes when revisiting complex bits. I always annotate my macros'. Also people sometimes find my personal stuff useful, and if its annotated It would be simpler to share and amend without getting drawn in.


Edited by sparkyhx on Monday 23 March 22:15

GnuBee

1,272 posts

215 months

Tuesday 24th March 2015
quotequote all
sparkyhx said:
very 'old school' approach from the era where programmers did a good job.....................In my opinion most of todays programmers are crap, they write crap code and throw it over the wall pretty much untested. However possibly a bit over the top.

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.
Assembly language though can be obtuse and very long winded in the extreme and does benefit from "rich" commenting and even then I'm not convinced you'd get a net benefit with comments like "Load register with value".

Comments like "assign the value 1 to the variable x" after a statement x = 1 are just not required; what additional value does it provide? All it does is obfuscate the actual code under a metric ton of superfluous information.

Sounds like we've both been around for the same period of time; what I see today is what I saw 30 years ago. There are good and bad programmers. There are many more programmers around now as advances in languages have "democratised" the process moving it away from the dominion of those who hand punched cards whilst shoveling coal into the Winchester drive.


grumbledoak

31,532 posts

233 months

Tuesday 24th March 2015
quotequote all
[redacted]

onomatopoeia

3,469 posts

217 months

Tuesday 24th March 2015
quotequote all
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.


SystemParanoia

Original Poster:

14,343 posts

198 months

Tuesday 24th March 2015
quotequote all
I noticed that I could not ssh into my server using the works wifi today, looks like the I.T boys have been making some firewall changes frown

I decided this is another excuse to spend far longer writing an automated solution, than it would take to just do it manually lol.

so I've spent the last two evenings working on this outbound port-scanner. I've managed to get it working, and so I've decided to show you guys.

you may notice that ive grabbed a few snippets of code from this very thread smile thanks for that guys smile


#! /usr/bin/env python3

import subprocess
import os
import time
successful_results = [] <-- curly braces

def port_scan(low_port, high_port):
website = "portquiz.net:"
for port_num in range(low_port, high_port):
port_to_scan = website + "%d" % port_num
successful_results[port_to_scan] = subprocess.Popen(["wget", "-qO ",
port_to_scan])
output()

def output():
while successful_results:
for result1, result2 in successful_results.items():
if result2.poll() is not None:
del successful_results[result1]
if result2.returncode == 0:
# Print string from the 13th index to omit un-needed url text
print("Port %s is open" % result1[13:])
elif result2.returncode == 1:
print("Port %s is blocked" % result1[13:])
else:
print("Port %s returns an error" % result1[13:])
break

def yes_response(resp):
# Check if string is a yes response and return true if so
YES_RESPONSES = ["y", "yes"]

resp = resp.lower()

if resp in YES_RESPONSES:
return True
else:
return False

def main():
while True:
try:
print("\nThis Programme will scan a range of outbound ports")
low_port = int(input("\nEnter start port: "))
high_port = int(input("Enter end port: "))
start_time = time.clock()
port_scan(low_port, high_port)
end_time = time.clock()
print("\nScan completed in ", end_time - start_time, " seconds")
except ValueError:
print ("\nPlease enter numbers and not letters")
main()
if not yes_response(input("\nDo you wish to perform another scan? Y/N : ")):
break

if __name__=="__main__":
try:
main()
# Attempt to make programme exit cleanly
except KeyboardInterrupt:
print("\n\nShutdown requested... exiting\n\n")
try:
exit()
except SystemExit:
os._exit(0)




I appear to be having an issue with my successful_results dictionary. it will only work where it is; everywhere else I put it, it throws error messages at me.

Edited by SystemParanoia on Tuesday 24th March 19:57 - To edit a comment in the code


Edited by SystemParanoia on Tuesday 24th March - To Neaten up the timing code 20:41


Edited by SystemParanoia on Tuesday 24th March 21:14

AlexS

1,551 posts

232 months

Tuesday 24th March 2015
quotequote all
One thought with your commenting. You state that you are printing the strings from the 13th index to the end. That is pretty obvious from the syntax of the following line. It would be more useful to state why you are looking at the strings from this position.

anonymous-user

54 months

Tuesday 24th March 2015
quotequote all
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.

Though worth noting that coming back to a bit of code written 3 years previously can be challenging so comments can provide useful pointers as how it works..

SystemParanoia

Original Poster:

14,343 posts

198 months

Tuesday 24th March 2015
quotequote all
good point.

Im printing from index 13 as all previous indexes ( indecies? ) contain the the url that's being scanned.

its a little sloppy in its current form, and im working on correctly segmenting my data to prevent the need to do this smile