HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Determining Pythagorean triples based on the hypotenuse

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
hypotenusethedeterminingtriplespythagoreanbased

Problem

Below is my written code to determine if, based on the hypotenuse, a Pythagorean triple is possible, and what are the lengths. I was wondering if there is a more efficient way of doing so.

#Victor C
#Determines if a right triangle with user inputted hypotenuse is capable of being a Pythagorean Triple

import math
triplecheck = True
while True:
    hypotenuse = int(input("Please enter the hypotentuse:")) #Smallest hypotenuse which results in a pythagorean triple is 5.
    if hypotenuse > 4:
        break
c = csqr = hypotenuse**2 #sets two variables to be equivalent to c^^2. c is to be modified to shorten factoring, csqr as a reference to set a value
if c % 2 != 0:   #even, odd check of value c, to create an integer when dividing by half.
    c = (c+1)//2
else:
    c = c//2
for b in range(1,c+1):  #let b^^2 = b || b is equal to each iteration of factors of c^^2, a is set to be remainder of c^^2 minus length b.
    a = csqr-b
    if (math.sqrt(a))%1 == 0 and (math.sqrt(b))%1 == 0: #if squareroots of a and b are both equal to 0, they are integers, therefore fulfilling conditions
       tripleprompt = "You have a Pythagorean Triple, with the lengths of "+str(int(math.sqrt(b)))+", "+str(int(math.sqrt(a)))+" and "+str(hypotenuse)
       print(tripleprompt)
       triplecheck = False
if triplecheck == True:
    print("Sorry, your hypotenuse does not make a Pythagorean Triple.")

Solution

First, let's write this with a little style, and go from there:

import math

def is_triple(hypotenuse):
    """return (a, b, c) if Pythagrean Triple, else None"""
    if hypotenuse < 4:
        return None

    c = hypotenuse ** 2

    for a in xrange(3, hypotenuse):
        b = math.sqrt(c - (a ** 2)) 
        if b == int(b):
            return a, int(b), hypotenuse

    return None


Now, I'll walk you through it, line by line, and show you how I got this.

I have no idea if this is more efficient, but it is written in better style, which is an important thing to consider.

import math


Always put your imports at the top of the module.

def is_triple(hypotenuse):


Here is say 'let's define some functionality, and encase a repeatable, reusable pattern of logic within it. The rest of my answer revolves around this, and is a major first step to programming in Python.

def is_triple(hypotenuse):
    """return (a, b, c) if Pythagrean Triple, else None"""


Note the """ triple quotes. That's your docstring, something that reminds you later what you were thinking when you wrote something. Try to keep it under 65 characters or so.

if hypotenuse < 4:
    return None


In the first line, def is_triple(hypotenuse):, I ask the user to give me something; a variable that I can use later. If I later call this function in the manner is_triple(5), I am basically telling the function that my hypotenuse is 5, and for the rest of the time here, we'll call it hypotenuse.

c = hypotenuse ** 2


That's really all you need for this calculation right now.

for a in xrange(3, hypotenuse):
        b = math.sqrt(c - (a ** 2)) 
        if b == int(b):
            return a, int(b), hypotenuse


for a in xrange(3, hypotenuse) basically says for each whole number between 3 and the hypotenuse, do the stuff I'm about to write.

Following the previous example,

>>> range(3, hypotenuse) #hypotenuse is == 5
[3, 4]


Nevermind that I call xrange(), it functions the same as far as we're concerned here, and importantly, is more efficient.

So now that we've made a loop, a will act as though it is each number in [3, 4], so first, it's 3:

b = math.sqrt(c -  (a ** 2))
b = math.sqrt(25 - (3 ** 2))
b = math.sqrt(25 - (9))
b = math.sqrt(16)
b = 4.0


Just like you would on pencil and paper. Notice I put a .0 after, the four. That's important here:

if b == int(b):


Basically, int puts the number b from a decimal to a whole number. We just check if they're the same.

>>> int(4.0)
4
>>> int(4.0) == 4
True


So, if the number we got for b is the same as the whole number representation of b, do the next part:

return a, int(b), hypotenuse


Which maps a value back to whatever you called as an assignment for the function call.

>>> values = is_triple(5)
>>> values
(3, 4, 5)
>>> wrong = is_triple(7)
>>> wrong
>>> #it didn't print anything, because it gave me back None


Finally, at the bottom:

return None


That's the last thing to catch, in case nothing else happens. Obviously, if you've gone through this loop and you haven't gotten an answer? Well, looks like you don't have a match. Give back a None to denote this.

To see this work in action, try this:

>>> import pprint
>>> pprint.pprint([{x: is_triple(x)} for x in xrange(101)])

Code Snippets

import math

def is_triple(hypotenuse):
    """return (a, b, c) if Pythagrean Triple, else None"""
    if hypotenuse < 4:
        return None

    c = hypotenuse ** 2

    for a in xrange(3, hypotenuse):
        b = math.sqrt(c - (a ** 2)) 
        if b == int(b):
            return a, int(b), hypotenuse

    return None
import math
def is_triple(hypotenuse):
def is_triple(hypotenuse):
    """return (a, b, c) if Pythagrean Triple, else None"""
if hypotenuse < 4:
    return None

Context

StackExchange Code Review Q#18171, answer score: 9

Revisions (0)

No revisions yet.