Trying to get into good code habbits

Trying to get into good code habbits

Author
Discussion

DoubleByte

1,254 posts

266 months

Wednesday 25th March 2015
quotequote all
dcb said:
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.
It's because you need 10 lines of comments to each line of code smilesmile

AlexS

1,551 posts

232 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).

Good coding is not about writing comments, good coding is about understanding the questions and providing answers.
Reducing the number of lines at the expense of readability is not a sensible way forward though. It is far more important that it can be understood 10 years in the future than reducing something down to a single line of incomprehensible code. If the thing is compiled, the compiler will generally sort the performance out anyway.

Sensible comments will also help with the understanding.

eharding

13,711 posts

284 months

Wednesday 25th March 2015
quotequote all
AlexS said:
It is far more important that it can be understood 10 years in the future than reducing something down to a single line of incomprehensible code.
Eminently sensible.

AlexS said:
If the thing is compiled, the compiler will generally sort the performance out anyway.
Complete, and utter, bks.


130R

6,810 posts

206 months

Thursday 26th March 2015
quotequote all
DoubleByte said:
dcb said:
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.
It's because you need 10 lines of comments to each line of code smilesmile
Not that I have anything against Python but it's nowhere near as prevalent as C / Java / C++. If you are studying programming with the aim of getting a job you would be much better off learning one of those languages.

onomatopoeia

3,469 posts

217 months

Thursday 26th March 2015
quotequote all
AlexS said:
If the thing is compiled, the compiler will generally sort the performance out anyway.
One of the reasons I still need assembly language from time to time is that this is not true.

scorp

8,783 posts

229 months

Thursday 26th March 2015
quotequote all
onomatopoeia said:
One of the reasons I still need assembly language from time to time is that this is not true.
That's kind of rare for most C/C++ applications.

Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
Ok, so I had a quick bash at the challenge set by TheExcession. A starter for 10, if you like.

I ripped off the OP's code (as it works fine and I couldn't really be arsed to write it again smile)

The functions for Sin, Cos and Tan are in there, but I haven't done anything with them yet, so there's no need to import math yet, but they're there for when needed, and lets face it, the time taken was miniscule. They're in there for later. Same with the 'numSides' variable, as may need that later. For something. Er....

I have conveniently ignored the 'no print statements allowed' requirement, as that needs more of a think.

#!/usr/bin/python

import math


class tri(object):

numSides = 3

def __init__(self, angle1, angle2, angle3):
self.angle1 = angle1
self.angle2 = angle2
self.angle3 = angle3

def checkValidTri(self):
if self.angle1 + self.angle2 + self.angle3 == 180:
return True
else:
return False

def checkEquilateral(self):
if (self.angle1 == self.angle2 == self.angle3):
return True
else:
return False

def checkRightAngle(self):
if self.angle1 == 90:
return True
elif self.angle2 == 90:
return True
elif self.angle3 == 90:
return True
else:
return False

def showSin(angle):
return sin(angle)

def showCOS(angle):
return cos(angle)

def showTAN(angle):
return tan(angle)

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 checks triangles\n"

try:
angle1 = float(raw_input("Enter 1st angle: "))
angle2 = float(raw_input("Enter 2nd angle: "))
angle3 = float(raw_input("Enter 3rd angle: "))
base = float(raw_input("Enter Base Value: "))
height = float(raw_input("Enter Height value: "))

except ValueError:
print "\nPlease enter numbers and not letters"
continue

mytri = tri(angle1, angle2, angle3)
valid = mytri.checkValidTri()
equilat = mytri.checkEquilateral()
rightAngle = mytri.checkRightAngle()

if valid:
print "\nValid triangle."
else:
print "\nNot a real triangle. Exiting..."
break

if equilat:
print "\nEquilateral triangle."
else:
print "\nNot equilateral."

if rightAngle:
print "\nRight-angled triangle."
else:
print "\nNot right-angled."

area = calc_area(base, height)

print "\nThe 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()


Edited by Tonsko on Thursday 26th March 18:37

Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
Although I've noticed a bug: checkRightAngle seems to be returning true all of the time.

Edit: bug fixed. I broke the right-angled check down into elif statements. Previously it was all in one line:

def checkRightAngle(self):
if self.angle1 or self.angle2 or self.angle 3 == 90:
return True
else:
return False


Not sure why it didn't work.

Edited by Tonsko on Thursday 26th March 15:56

TheExcession

11,669 posts

250 months

Thursday 26th March 2015
quotequote all
Oh Lordy... here we go with another Internet argument. Let us put this to bed RIGHT NOW.

grumbledoak said:
Fewest key-presses or lines of code as a measure of quality is laughable.
AlexS said:
Reducing the number of lines at the expense of readability is not a sensible way forward though.
Please read what I wrote...

TheExcession said:
'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 did NOT say it was all about stuffing everything into one line of code, I did NOT say 'reduce the number of lines at the expense of readability'.

Perhaps I should have used the word 'fewer' rather than 'fewest' - there is no excuse for writing poor code, and a good coder should not be writing verbose code.

That is what I meant by fewer key presses - as a coder you are paid to solve problems, you should do that eloquently, elegantly and even stylishly if you like, it must always be well structured, readable and understandable.

In my past I have come across code with circa 15 nested if-then-else statements, at the same time I've written 6bit SNMP OID mapping code which was very heavily commented, then you might decide you need an MD5 hash function, how many comments and lines of code would you require to make that workable?

Honestly, I can't believe I got pulled up on a comment about reducing key-presses when your job is about delivering good code and you can measure the amount of time it takes to deliver in terms of key-presses.






grumbledoak

31,534 posts

233 months

Thursday 26th March 2015
quotequote all
Tonsko said:
code...
Bearing in mind some basic triangle facts wink:
https://www.mathsisfun.com/triangle.html


Appraisal:

Your 'tri' class only models right-angled triangles, so it is poorly named
Your 'tri' class allows you to create any type of triangle, for which it will not work, without raising any form of error

'numSides' is not needed. It's a triangle. It's going to be three.
'showSIN', 'showCOS', 'showTAN' are not part of the requirements, and not used, so
'math' is not needed

The area calculation might want to be method of your 'tri' class, assuming we are merging the requirements


Here is my attempt, given my understanding of the requirements and my lack of a python interpreter... wink

#!/usr/bin/python

class RightAngledTriangle(object):

def __init__(self, base, height):
""" Store them, maybe work out the other two angles now
if (base > 0) and (height > 0):
self.base = base
self.height = height
else:
raise Exception("Invalid (negative) length")

def Area()
return base * height / 2

def main():
YES_RESPONSES = ["y", "Y", "yes", "YES"]

while True:
print "\nThis programme checks triangles\n"

try:
angle1 = float(raw_input("Enter 1st angle (must be 90): "))
if (angle1 == 90):

base = float(raw_input("Enter base: "))
if (base > 0):

height = float(raw_input("Enter height: "))
if (height > 0):

mytri = RightAngledTriangle(base, height)
area = mytri.Area()

print ""The area of that triangle is: ", area
else:
print "Don't be clever"

else:
print "Stop mucking about"

else:
print "Those triangles are a bit too complicated for us at present"

reply = raw_input("\nDo you wish to continue? Y/N ")
if not reply in YES_RESPONSES:
break

except ValueError:
print "\nPlease enter numbers and not letters"
continue

print "\nGood Bye\n"


if __name__=="__main__":
main()


It is probably "too verbose" for some. Personally I think it should be more sarcastic.

Edit: stupid significant whitespace.


Edited by grumbledoak on Thursday 26th March 20:34

TheExcession

11,669 posts

250 months

Thursday 26th March 2015
quotequote all
Tonsko said:
Ok, so I had a quick bash at the challenge set by TheExcession. A starter for 10, if you like.

#!/usr/bin/python
Triangle code
That's a bloody good effort there,! Are you allowed multiple constructors in Python?

I'm thinking could you have a class triangle constructor that takes the x,y points of the corners a,b,c instead of just the angles that you have used?

What other constructors of the triangle class might be useful?

Secondly, is there anyway you can move the user input checking into the triangle class? The thinking here is that it should not be the responsibility of your 'main' code to 'know' what the triangle class needs - your main block should just ask a triangle class to do its stuff.

Think about what happens when we decide we need a circle, square, rectangle, sphere, cone, cylinder calculation too? Some volume calculations are creeping in now (panic?), this is called "scope creep" and is the killer to any programer who doesn't understand the problem he is deciding to solve.

So now we know there are (will always be) these entities that we didn't even know existed before, all now require very different bits of information in order to 'exist' and do their job.

So my way of dealing with this would be to set up the main program/class as offering all the available options "Type: T for Triangle, R for Rectangle, C for Circle".

As a code writer your job is to mediate between Humans and your code and other peoples code (don't forget that every input to any code you write was likely written by a Human).

People forget there is a 'management structure' in writing code, your code should be bullet proof in what it can do, beyond that all it should do is report the error.












Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
In my defence, I spent about half an hour on it at the end of the day and didn't think about it too hard before chucking it up and making it work. It was mainly an exercise for myself to make classes work as I've never used them. Also, the numSides thing I put in as a potential error checker for some unamed future thing. Probably worthless though, agreed. As for the SOHCAHTOA ones, again, put in there for future, proper functionality tba.

I couldn't get it to chuck an error grumbledoak - at what point would it bleat?

The input checking etc. agreed should be moved into the triangle class, as that would then allow you build other shape classes - it's more modular, and we like modular smile

Re: multiple constructors, I had to look them up. Stack Overflow tells me that Python doesn't support multiple constructors, but there are workarounds, i/e/ assign default values, if that's similar?

I re-used the area code just to get it to 'do' something with minimal effort and no errors to fill the time smile

But thanks! Points taken.

Edited by Tonsko on Thursday 26th March 20:53

grumbledoak

31,534 posts

233 months

Thursday 26th March 2015
quotequote all
Tonsko said:
I couldn't get it to chuck an error grumbledoak - at what point would it bleat?
I don't think your code will 'bleat' - that's the problem! It carries on with an invalid 'tri' for several lines. You should make that impossible, not rely on the caller checking 'valid' before using it.

And your 'if' issue was probably precedence because you were trying to be terse. You need to be careful when you do that. Better still, never do it.


def checkRightAngle(self):
if (self.angle1 == 90) or (self.angle2 == 90) or (self.angle 3 == 90):
return True
else:
return False




TheExcession

11,669 posts

250 months

Thursday 26th March 2015
quotequote all
[redacted]

Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
grumbledoak said:
I don't think your code will 'bleat' - that's the problem! It carries on with an invalid 'tri' for several lines. You should make that impossible, not rely on the caller checking 'valid' before using it.
Ah, I think I see - but how can you tell if it's an invalid triangle before you've added everything up to 180? I suppose you could put some incremental checking when entering angles - e.g. if the first two are less than 60, then the last one has to be greater than 100 or something.

Thanks for the if clarification, I didn't think to split it like that.

grumbledoak

31,534 posts

233 months

Thursday 26th March 2015
quotequote all
Tonsko said:
Ah, I think I see - but how can you tell if it's an invalid triangle before you've added everything up to 180? I suppose you could put some incremental checking when entering angles - e.g. if the first two are less than 60, then the last one has to be greater than 100 or something.
The angles are not independent. Don't provide an interface that lets them change one at a time.

TheExcession

11,669 posts

250 months

Thursday 26th March 2015
quotequote all
My understanding is that we are trying to help a person get a good start with programming. We're not actually here trying to out do the other Internet bloke?

Did I miss one of the requirements?

Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
I feel I'm being a bit thick. Why are you forcing the angle to be 90? If the input must be 90, why bother asking for the input?

Tonsko

6,299 posts

215 months

Thursday 26th March 2015
quotequote all
TheExcession said:
My understanding is that we are trying to help a person get a good start with programming. We're not actually here trying to out do the other Internet bloke?

Did I miss one of the requirements?
This is true, I'm diverting the thread and getting bogged down with details.

grumbledoak

31,534 posts

233 months

Thursday 26th March 2015
quotequote all
Tonsko said:
I feel I'm being a bit thick. Why are you forcing the angle to be 90?
The base * height / 2 calculation of area of a triangle (where we started) is only valid for right angled triangles. So the code either works correctly or refuses to attempt it.