Skip to content

Commit

Permalink
Merge 2f65900 into 3ecf242
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian-B committed Feb 13, 2020
2 parents 3ecf242 + 2f65900 commit 250e80f
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
58 changes: 58 additions & 0 deletions spinn_utilities/helpful_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@
import logging
import inspect
import re
from six.moves import reduce
import sys
from six import string_types

if sys.version_info >= (3, 5):
from math import gcd as _gcd # pylint: disable=no-name-in-module
else:
from fractions import gcd as _gcd # noqa: ignore=W1505

logger = logging.getLogger(__name__)
FINISHED_FILENAME = "finished"

Expand Down Expand Up @@ -47,3 +54,54 @@ def is_singleton(value):
to represent an iterable of characters
"""
return not hasattr(value, '__iter__') or isinstance(value, string_types)


def _lcm(a, b):
return (a * b) // _gcd(a, b) # noqa: ignore=W1505 # pylint: disable=deprecated-method


def lcm(*numbers):
"""
Lowest common multiple of 0, 1 or more integers.
GIGO: If any of the values are anything except positive int values\
this function will either produce incorrect results or raise an exception.
:param numbers: The Positive integers to get the lcm for.\
This can be zero, one or more int values or\
a singelton which is an iterator (possibly empty) of ints.
:return: the lcm or 1 if numbers is empty or an empty iterator
:rtype: int
:raises TypeError: If any value can not be interpreted as an Integer
:raises ZeroDivisionError: May be raised if one of the values is zero
"""
if len(numbers) == 1:
try:
return reduce(_lcm, iter(numbers[0]), 1)
except TypeError:
return numbers[0]
return reduce(_lcm, numbers, 1)


def gcd(*numbers):
"""
Greatest Common Divisor of 1 or more integers.
GIGO: If any of the values are anything except positive int values\
this function will either produce incorrect results or raise an exception.
:param numbers: The Positive integers to get the lcm for.\
This can be one or more int values or\
a singelton which is an iterator (not empty) of ints.
:return: the lcm or 1 if numbers is empty or an empty iterator
:rtype: int
:raises TypeError: If any value can not be interpreted as an Integer or\
if no value a are provided
:raises ZeroDivisionError: May be raised if one of the values is zero
"""
if len(numbers) == 1:
try:
return reduce(_gcd, iter(numbers[0]))
except TypeError:
return numbers[0]
return reduce(_gcd, numbers)
28 changes: 27 additions & 1 deletion unittests/test_helpful_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import unittests
from spinn_utilities.helpful_functions import (
get_valid_components, is_singleton)
get_valid_components, is_singleton, gcd, lcm)


def test_is_singleton():
Expand All @@ -42,6 +42,32 @@ def test_get_valid_components():
assert d['b'] == b_c


def test_gcd():
assert gcd(2) == 2
assert gcd(30, 40) == 10
assert gcd(120, 40, 60) == 20
a = [2, 3, 4]
assert gcd(a) == 1
b = set([1000, 500, 1500])
assert gcd(b) == 500
c = [34]
assert gcd(c) == 34


def test_lcm():
assert lcm(2) == 2
assert lcm(30, 40) == 120
assert lcm(120, 40, 60) == 120
assert lcm() == 1
assert lcm([]) == 1
a = [2, 3, 4]
assert lcm(a) == 12
b = set([1000, 500, 1500])
assert lcm(b) == 3000
c = [34]
assert lcm(c) == 34


# Support class for test_get_valid_components
class a_b(object): # noqa: N801
pass
Expand Down

0 comments on commit 250e80f

Please sign in to comment.