After my first exercise here is another. Again, this is exactly that: Exercise, which means that the output doesn't necessarily need to be beautifully formatted, etc. I probably have some variable naming issues around and also more general issues.
# coding=utf-8
"""Basic usage:
$ python xggt.py 3343 77
(1, -12, 521)
65
"""
import argparse
###############################################################################
def main():
"""Prints out the results of xggt().
xggt() takes two non-optional integers as arguments.
"""
parser = argparse.ArgumentParser()
parser.add_argument('num_1', type=int)
parser.add_argument('num_2', type=int)
args = parser.parse_args()
if (args.num_1 == 0) and (args.num_2 == 0):
print("Please enter two positive integers.")
else:
print(xggt(args.num_1, args.num_2))
print(modinv(args.num_1, args.num_2))
###############################################################################
def xggt(num_1, num_2):
"""Implements the Extended Euclidean algorithm.
Returns the greatest common divisor of two integers > 0.
Also returns the coefficients of Bézout’s identity.
"""
if num_1 % num_2 == 0:
return(num_2, 0, 1)
else:
gcd, lin_fact_1, lin_fact_2 = xggt(num_2, num_1 % num_2)
lin_fact_1 = lin_fact_1 - num_1 // num_2 * lin_fact_2
return(gcd, lin_fact_2, lin_fact_1)
###############################################################################
def modinv(num_1, num_2):
"""Returns the modular multiplicative inverse of two integers > 0
"""
gcd, lin_fact_1, _ = xggt(num_1, num_2)
if gcd != 1:
return None
else:
return lin_fact_1 % num_2
###############################################################################
if __name__ == '__main__':
main()
xggt
) is nice and tight. I like it, but my head spins trying to match it against the math... Perhaps it would be easier to see the elegance of it if you used shorter names (single letters, corresponding to the letters u, v, s, r used in the formulas). \$\endgroup\$else
in xggt, though. It is confusing because it's superfluous. \$\endgroup\$else
. \$\endgroup\$parser
is undefined inmain()
2)lin_fact_2
is undefined inxggt()
. The first error is easy to fix, but the second makes it difficult to understand your algorithm. \$\endgroup\$gcd, lin_fact_1, lin_fact_2 = xggt(num_2, num_1 % num_2)
inxggt()
. \$\endgroup\$