#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!

import sys
if __name__ == "__main__":
    sys.modules.setdefault("MainAndExtraCode", sys.modules[__name__])


class MainAndExtraCode:
    """A Python main is launched with the full sys.argv, and extra class code is class-level Python."""

    def __init__(self):
        pass

    def delete(self):
        pass

    @staticmethod
    def main(args):
        # line 5 "MainAndExtraCode.ump"
        print(MainAndExtraCode.GREETING, len(args))
        # end line

    # line 8 "MainAndExtraCode.ump"
    GREETING = "hello"
    def helper(self):
        return self.GREETING
    # end line


if __name__ == "__main__":
    MainAndExtraCode.main(sys.argv)

#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!


class MethodWrappers:
    """Contracts and injections wrap a method; the body runs in a helper bound to the declaring class."""

    def __init__(self):
        pass

    def delete(self):
        pass

    def half(self, x):
        if not (x > 0):
            raise RuntimeError("Please provide a valid x")
        result = __class__.half_Original(self, x)
        if not (result < x):
            raise RuntimeError("Please provide a valid result and x")
        return result

    def half_Original(self, x):
        # line 7 "MethodWrappers.ump"
        return x // 2
        # end line

    @staticmethod
    def bounded(x):
        if not (x < 100):
            raise RuntimeError("Please provide a valid x")
        # line 12 "MethodWrappers.ump"
        return x
        # end line

    def logged(self, x):
        # line 28 "MethodWrappers.ump"
        print("before", x)
        # end line
        result = __class__.logged_Original(self, x)
        # line 29 "MethodWrappers.ump"
        print("after")
        # end line
        return result

    def logged_Original(self, x):
        # line 16 "MethodWrappers.ump"
        return x + 1
        # end line

    def keep(self, result):
        if not (result > 0):
            raise RuntimeError("Please provide a valid result")
        # line 21 "MethodWrappers.ump"
        return result * 2
        # end line

    def m(self):
        # line 30 "MethodWrappers.ump"
        print("m")
        # end line
        # line 24 "MethodWrappers.ump"
        return 1
        # end line

    def m_Original(self):
        # line 26 "MethodWrappers.ump"
        return 2
        # end line

#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!

import datetime


class OverloadedMethods:
    """Overloaded methods become numbered implementations and a dispatcher that binds the arguments."""

    def __init__(self):
        pass

    def delete(self):
        pass

    def describe1(self, value):
        # line 6 "OverloadedMethods.ump"
        return "int"
        # end line

    def describe2(self, value, flag):
        # line 7 "OverloadedMethods.ump"
        return "pair"
        # end line

    def describe3(self, part):
        # line 8 "OverloadedMethods.ump"
        return "part"
        # end line

    def describe4(self, names):
        # line 9 "OverloadedMethods.ump"
        return "names"
        # end line

    def describe5(self, day):
        # line 10 "OverloadedMethods.ump"
        return "day"
        # end line

    def describe(self, *args, **kwargs):
        from Part import Part
        bound = __class__._bindArguments(("value",), False, args, kwargs)
        if bound is not None and (bound[0] is None or (isinstance(bound[0], int) and not isinstance(bound[0], bool))):
            return __class__.describe1(self, *bound)
        bound = __class__._bindArguments(("value", "flag"), False, args, kwargs)
        if bound is not None and (bound[0] is None or (isinstance(bound[0], (int, float)) and not isinstance(bound[0], bool))) and (bound[1] is None or isinstance(bound[1], bool)):
            return __class__.describe2(self, *bound)
        bound = __class__._bindArguments(("part",), False, args, kwargs)
        if bound is not None and (bound[0] is None or isinstance(bound[0], Part)):
            return __class__.describe3(self, *bound)
        bound = __class__._bindArguments(("names",), False, args, kwargs)
        if bound is not None and (bound[0] is None or isinstance(bound[0], (list, tuple)) and all((e is None or isinstance(e, str)) for e in bound[0])):
            return __class__.describe4(self, *bound)
        bound = __class__._bindArguments(("day",), False, args, kwargs)
        if bound is not None and (bound[0] is None or isinstance(bound[0], datetime.date)):
            return __class__.describe5(self, *bound)
        raise TypeError("No method matches provided parameters")

    @staticmethod
    def combine1(a):
        # line 11 "OverloadedMethods.ump"
        return a
        # end line

    @staticmethod
    def combine2(a, b):
        # line 12 "OverloadedMethods.ump"
        return a + b
        # end line

    @staticmethod
    def combine(*args, **kwargs):
        bound = __class__._bindArguments(("a",), False, args, kwargs)
        if bound is not None and (isinstance(bound[0], int) and not isinstance(bound[0], bool)):
            return __class__.combine1(*bound)
        bound = __class__._bindArguments(("a", "b"), False, args, kwargs)
        if bound is not None and (isinstance(bound[0], int) and not isinstance(bound[0], bool)) and (isinstance(bound[1], int) and not isinstance(bound[1], bool)):
            return __class__.combine2(*bound)
        raise TypeError("No method matches provided parameters")

    def count2(self, *values):
        # line 13 "OverloadedMethods.ump"
        return len(values)
        # end line

    def count3(self, text):
        # line 14 "OverloadedMethods.ump"
        return -1
        # end line

    def count(self, *args, **kwargs):
        bound = __class__._bindArguments(("text",), False, args, kwargs)
        if bound is not None and (bound[0] is None or isinstance(bound[0], str)):
            return __class__.count3(self, *bound)
        bound = __class__._bindArguments((), True, args, kwargs)
        if bound is not None and all((isinstance(v, int) and not isinstance(v, bool)) for v in bound[0]):
            return __class__.count2(self, *bound[:-1], *bound[-1])
        raise TypeError("No method matches provided parameters")

    def count1(self):
        # line 15 "OverloadedMethods.ump"
        return 99
        # end line

    @staticmethod
    def _bindArguments(names, varargs, args, kwargs):
        if len(args) > len(names) and not varargs:
            return None
        bound = list(args[:len(names)])
        for name in names[len(bound):]:
            if name not in kwargs:
                return None
            bound.append(kwargs[name])
        if len(kwargs) != len(names) - min(len(args), len(names)):
            return None
        if varargs:
            bound.append(args[len(names):])
        return bound

#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!

from abc import ABC
from abc import abstractmethod


class Shape(ABC):
    """Abstract methods are abstract stubs, and a class gets a stub for an interface method it lacks."""

    def __init__(self):
        pass

    def delete(self):
        pass

    @abstractmethod
    def area(self):
        pass

#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!

from Shape import Shape
from Measured import Measured


class Square(Shape, Measured):
    def __init__(self):
        super().__init__()

    def delete(self):
        super().delete()

    def area(self):
        # line 17 "AbstractMethods.ump"
        return 4.0
        # end line

    def unit(self):
        # line 18 "AbstractMethods.ump"
        return "cm"
        # end line

    def size(self):
        return 0

#PLEASE DO NOT EDIT THIS CODE
#This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!


class NativeMethods:
    """Native method bodies: untagged bodies are Python, tagged Python bodies win, other languages are left out."""

    def __init__(self):
        pass

    def delete(self):
        pass

    def evens(self, n):
        """Sums the even numbers below n."""
        # line 6 "NativeMethods.ump"
        total = 0
        for i in range(n):
            if i % 2 == 0:
                total += i
        return total
        # end line

    def text(self):
        # line 14 "NativeMethods.ump"
        return """one
  two"""
        # end line

    def chosen(self):
        # line 21 "NativeMethods.ump"
        return "python"
        # end line

    def nothing(self):
        pass

    @staticmethod
    def twice(input):
        # line 30 "NativeMethods.ump"
        return input * 2
        # end line