All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.org.python.modules.itertools.itertools Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
/* Copyright (c) Jython Developers */
package org.python.modules.itertools;

import org.python.core.ClassDictInit;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyIterator;
import org.python.core.PyNone;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PyTuple;

/**
 * Functional tools for creating and using iterators. Java implementation of the CPython module
 * itertools.
 * 
 * @since 2.5
 */
public class itertools implements ClassDictInit {

    public static PyString __doc__ = new PyString(
            "Functional tools for creating and using iterators.\n\nInfinite iterators:\n"
	        + "count([n]) --> n, n+1, n+2, ...\n"
	        + "cycle(p) --> p0, p1, ... plast, p0, p1, ...\n"
	        + "repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\n"
	    
	        + "Iterators terminating on the shortest input sequence:\n"
	        + "chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n"
	        + "compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n"
	        + "dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n"
	        + "groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n"
	        + "ifilter(pred, seq) --> elements of seq where pred(elem) is True\n"
	        + "ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n"
	        + "islice(seq, [start,] stop [, step]) --> elements from seq[start:stop:step]\n"
	        + "imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n"
	        + "starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n"
	        + "tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n"
	        + "takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n"
	        + "izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n"
	        + "izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\n"

	        + "Combinatoric generators:\n"
	        + "product(p, q, ... [repeat=1]) --> cartesian product\n"
	        + "permutations(p[, r])\n"
	        + "combinations(p, r)\n"
	        + "combinations_with_replacement(p, r)");

    /**
     * Iterator base class used by most methods.
     */
    static abstract class ItertoolsIterator extends PyIterator {

        /**
         * Returns the next element from an iterator. If it raises/throws StopIteration just store
         * the Exception and return null according to PyIterator practice.
         */
        protected PyObject nextElement(PyObject pyIter) {
            PyObject element = null;
            try {
                element = pyIter.__iternext__();//next();
            } catch (PyException pyEx) {
                if (pyEx.match(Py.StopIteration)) {
                    // store exception - will be used by PyIterator.next()
                    stopException = pyEx;
                } else {
                    throw pyEx;
                }
            }
            return element;
        }
    }

    public static void classDictInit(PyObject dict) {
        dict.__setitem__("__name__", new PyString("itertools"));
        dict.__setitem__("__doc__", __doc__);
        dict.__setitem__("chain", chain.TYPE);
        dict.__setitem__("combinations", combinations.TYPE);
        dict.__setitem__("combinations_with_replacement", combinationsWithReplacement.TYPE);
        dict.__setitem__("compress", compress.TYPE);
        dict.__setitem__("cycle", cycle.TYPE);
        dict.__setitem__("count", count.TYPE);
        dict.__setitem__("dropwhile", dropwhile.TYPE);
        dict.__setitem__("groupby", groupby.TYPE);
        dict.__setitem__("imap", imap.TYPE);
        dict.__setitem__("ifilter", ifilter.TYPE);
        dict.__setitem__("ifilterfalse", ifilterfalse.TYPE);
        dict.__setitem__("islice", islice.TYPE);
        dict.__setitem__("izip", izip.TYPE);
        dict.__setitem__("izip_longest", izipLongest.TYPE);
        dict.__setitem__("permutations", permutations.TYPE);
        dict.__setitem__("product", product.TYPE);
        dict.__setitem__("repeat", repeat.TYPE);
        dict.__setitem__("starmap", starmap.TYPE);
        dict.__setitem__("takewhile", takewhile.TYPE);

        // Hide from Python
        dict.__setitem__("classDictInit", null);
        dict.__setitem__("initClassExceptions", null);
    }

    public static PyString __doc__islice = new PyString(
            "islice(iterable, [start,] stop [, step]) --> islice object\n"
                    + "\nReturn an iterator whose next() method returns selected values from an\n"
                    + "iterable.  If start is specified, will skip all preceding elements;\notherwise, start defaults to zero."
                    + "Step defaults to one.  If\nspecified as another value, step determines how manyvalues are \n"
                    + "skipped between successive calls.  Works like a slice() on a list\nbut returns an iterator.");

    
    static int py2int(PyObject obj, int defaultValue, String msg) {
        if (obj instanceof PyNone) {
            return defaultValue;
        } else {
            int value = defaultValue;
            try {
                value = Py.py2int(obj);
            }
            catch (PyException pyEx) {
                if (pyEx.match(Py.TypeError)) {
                    throw Py.ValueError(msg);
                } else {
                    throw pyEx;
                }
            }
            return value;
        }
    }

    /**
     * Iterator base class for iterators returned by ifilter and
     * ifilterfalse.
     */
    static class FilterIterator extends ItertoolsIterator {
        private PyObject predicate;

        private PyObject iterator;

        private boolean filterTrue;

        FilterIterator(PyObject predicate, PyObject iterable, boolean filterTrue) {
            if (predicate instanceof PyNone) {
                this.predicate = null;
            } else {
                this.predicate = predicate;
            }
            this.iterator = iterable.__iter__();
            this.filterTrue = filterTrue;
        }

        public PyObject __iternext__() {

            while (true) {
                PyObject element = nextElement(iterator);
                if (element != null) {
                    // the boolean value of calling predicate with the element
                    // or if predicate is null/None of the element itself
                    boolean booleanValue = predicate != null ? predicate
                            .__call__(element).__nonzero__() : element
                            .__nonzero__();
                    if (booleanValue == filterTrue) {
                        // if the boolean value is the same as filterTrue return
                        // the element
                        // for ifilter filterTrue is always true, for
                        // ifilterfalse always false
                        return element;
                    }
                } else {
                    return null;
                }
            }
        }
    }

    /**
     * Iterator base class used by dropwhile() and takewhile.
     */
    static class WhileIterator extends ItertoolsIterator {
        private PyObject iterator;

        private PyObject predicate;

        // flag that indicates if the iterator shoul drop or return arguments "while" the predicate is true
        private boolean drop;

        // flag that is set once the predicate is satisfied
        private boolean predicateSatisfied;

        WhileIterator(PyObject predicate, PyObject iterable, boolean drop) {
            this.predicate = predicate;
            iterator = iterable.__iter__();
            this.drop = drop;
        }

        public PyObject __iternext__() {

            while (true) {
                PyObject element = nextElement(iterator);
                if (element != null) {
                    if (!predicateSatisfied) {
                        // the predicate is not satisfied yet (or still satisfied in the case of drop beeing 
                        // false), so we need to check it
                        if (predicate.__call__(element).__nonzero__() != drop) {
                            predicateSatisfied = drop;
                            return element;
                        }
                        predicateSatisfied = !drop;
                    } else {
                        if (drop) {
                            return element;
                        } else {
                            // end iteration if predicate is false and drop is false
                            return null;
                        }
                    }
                } else {
                    // end iteration
                    return null;
                }

            }
        }
    }

    public static PyString __doc__tee = new PyString(
            "tee(iterable, n=2) --> tuple of n independent iterators.");

    /**
     * Create a tuple of iterators, each of which is effectively a copy of iterable.
     */
    public static PyTuple tee(PyObject iterable, final int n) {
        return new PyTuple(PyTeeIterator.makeTees(iterable, n));
    }

    /**
     * Create a pair of iterators, each of which is effectively a copy of iterable.
     */
    public static PyTuple tee(PyObject iterable) {
        return tee(iterable, 2);
    }

    static PyTuple makeIndexedTuple(PyTuple pool, int indices[]) {
        return makeIndexedTuple(pool, indices, indices.length);
    }
    
    static PyTuple makeIndexedTuple(PyTuple pool, int indices[], int end) {
        PyObject items[] = new PyObject[end];
        for (int i = 0; i < end; i++) {
            items[i] = pool.__getitem__(indices[i]);
        }
        return new PyTuple(items);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy