[ale] Python: help me??

David Jackson deepbsd.ale at gmail.com
Wed Jun 17 17:52:12 EDT 2015


Hi,

I've been taking a Python class from OReilly School of Technology since
about November or so.  I'm finally on the last of four courses, and this
course is called Advanced Python.  I don't feel very advanced!  But this
assignment is about using __magic__ methods in a composable class, and I've
got a problem.

Here's the class from a file called composable.py:

*** snip ***

#!/usr/bin/env python3

"""
composable.py: defines a composable function class.
"""

import types

class Composable:
    def __init__(self, f):
        "Store reference to proxied function."
        self.func = f

    def __call__(self, *args, **kwargs):
        "Proxy the function, passing all arguments through."
        return self.func(*args, **kwargs)

    def __pow__(self, other):
        "Return the composition of x to the power of y"
        if other > 0:
            for i in range(other-1):
                self *= self
            return self
        else:
            raise ValueError("Needs to be positive integer.")


    def __mul__(self, other):
        "Return the composition of proxied and another function."
        if type(other) is Composable:
            def anon(x):
                return self.func(other.func(x))
            return Composable(anon)
        elif type(other) is types.FunctionType:
            def anon(x):
                return self.func(other(x))
            return Composable(anon)
        raise TypeError("Illegal operands for multiplication")

    def __repr__(self):
        return "<Composable function {0} at
0x{1:X}>".format(self.func.__name__, id(self))

*** snip ***

The test is test_composable.py:

*** snip ***

#!/usr/bin/env python3

"""
test_composable.py: performs simple tests of composable functions.
"""

import unittest
from composable import Composable

def reverse(s):
    "Reverses a string using negative-stride sequencing."
    return s[::-1]

def square(x):
    "Multiplies a number by itself."
    return x*x

def pow(x, y):
    "raise x to the power of y"
    return x**y


class ComposableTestCase(unittest.TestCase):

    def test_inverse(self):
        reverser = Composable(reverse)
        nulltran = reverser * reverser
        for s in "", "a", "0123456789", "abcdefghijklmnopqrstuvwxyz":
            self.assertEqual(nulltran(s), s)

    def test_pow(self):
        a = 0
        for a in (2,3,4):
            b = pow(pow(a,a), pow(a,a))
            square1 = Composable(pow)
            square2 = Composable(pow)
            # should equal pow(pow(x,x), pow(x,x))
            xtimespwr = pow(square1(a,a), square2(a,a))
            self.assertEqual(xtimespwr, b)
        with self.assertRaises(ValueError):
            oops = square1(2,-2)
        with self.assertRaises(TypeError):
            oops = square1(3, 'a')

    def test_square(self):
        squarer = Composable(square)
        po4 = squarer * squarer
        for v, r in ((1,1), (2, 16), (3, 81)):
            self.assertEqual(po4(v), r)

    def test_exceptions(self):
        fc = Composable(square)
        with self.assertRaises(TypeError):
            fc = fc * 3
        with self.assertRaises(TypeError):
            fc = square * fc

if __name__ == "__main__":
    unittest.main()

*** snip ***

Everything passes except the ValueError test in test_pow. (When I comment
the ValueError test out, the unittest passes.) I should think I was
triggering that special __pow__ function, but I might be triggering the
built-in pow().    Any insights on why the ValueError isn't getting
triggered?

Thanks!
Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.ale.org/pipermail/ale/attachments/20150617/6d40cdca/attachment.html>


More information about the Ale mailing list