Trying to get into good code habbits
Discussion
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.
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.Good coding is not about writing comments, good coding is about understanding the questions and providing answers.
Sensible comments will also help with the understanding.
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.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.
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 )
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.
I ripped off the OP's code (as it works fine and I couldn't really be arsed to write it again )
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
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:
Not sure why it didn't work.
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
Oh Lordy... here we go with another Internet argument. Let us put this to bed RIGHT NOW.
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 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.
Tonsko said:
code...
Bearing in mind some basic triangle facts :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...
#!/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
Tonsko said:
Ok, so I had a quick bash at the challenge set by TheExcession. A starter for 10, if you like.
That's a bloody good effort there,! Are you allowed multiple constructors in Python?#!/usr/bin/python
Triangle code
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.
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
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
But thanks! Points taken.
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
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
But thanks! Points taken.
Edited by Tonsko on Thursday 26th March 20:53
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
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.
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 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.Did I miss one of the requirements?
Gassing Station | Computers, Gadgets & Stuff | Top of Page | What's New | My Stuff