[Python-checkins] python/nondist/sandbox/itertools itertools.c,1.6,1.7 test_itertools.py,1.4,1.5 todo.txt,1.7,1.8

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Mon, 27 Jan 2003 03:17:48 -0800


Update of /cvsroot/python/python/nondist/sandbox/itertools
In directory sc8-pr-cvs1:/tmp/cvs-serv1395

Modified Files:
	itertools.c test_itertools.py todo.txt 
Log Message:
Added takewhile().

Index: itertools.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/itertools.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** itertools.c	27 Jan 2003 10:44:52 -0000	1.6
--- itertools.c	27 Jan 2003 11:17:45 -0000	1.7
***************
*** 2,5 ****
--- 2,147 ----
  #include "Python.h"
  
+ /* takewhile object ************************************************************/
+ 
+ typedef struct {
+ 	PyObject_HEAD
+ 	PyObject *func;
+ 	PyObject *it;
+ 	long	 stop;
+ } takewhileobject;
+ 
+ PyTypeObject takewhile_type;
+ 
+ static PyObject *
+ takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ 	PyObject *func, *seq;
+ 	PyObject *it;
+ 	takewhileobject *lz;
+ 
+ 	if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
+ 		return NULL;
+ 
+ 	/* Get iterator. */
+ 	it = PyObject_GetIter(seq);
+ 	if (it == NULL)
+ 		return NULL;
+ 
+ 	/* create takewhileobject structure */
+ 	lz = (takewhileobject *)type->tp_alloc(type, 0);
+ 	if (lz == NULL) {
+ 		Py_DECREF(it);
+ 		return NULL;
+ 	}
+ 	Py_INCREF(func);
+ 	lz->func = func;
+ 	lz->it = it;
+ 	lz->stop = 0;
+ 
+ 	return (PyObject *)lz;
+ }
+ 
+ static void
+ takewhile_dealloc(takewhileobject *lz)
+ {
+ 	PyObject_GC_UnTrack(lz);
+ 	Py_XDECREF(lz->func);
+ 	Py_XDECREF(lz->it);
+ 	lz->ob_type->tp_free(lz);
+ }
+ 
+ static int
+ takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg)
+ {
+ 	if (lz->it)
+ 		return visit(lz->it, arg);
+ 	return 0;
+ }
+ 
+ static PyObject *
+ takewhile_next(takewhileobject *lz)
+ {
+ 	PyObject *item, *good;
+ 	long ok;
+ 
+ 	if (lz->stop == 1)
+ 		return NULL;
+ 
+ 	item = PyIter_Next(lz->it);
+ 	if (item == NULL)
+ 		return NULL;
+ 
+ 	good = PyObject_CallFunctionObjArgs(lz->func, item, NULL);
+ 	if (good == NULL) {
+ 		Py_DECREF(item);
+ 		return NULL;
+ 	}
+ 	ok = PyObject_IsTrue(good);
+ 	Py_DECREF(good);
+ 	if (ok)
+ 		return item;
+ 	Py_DECREF(item);
+ 	lz->stop = 1;
+ 	return NULL;
+ }
+ 
+ static PyObject *
+ takewhile_getiter(PyObject *lz)
+ {
+ 	Py_INCREF(lz);
+ 	return lz;
+ }
+ 
+ PyDoc_STRVAR(takewhile_doc,
+ "takewhile(predicate, sequence) --> takewhile object\n\
+ \n\
+ Return those items of sequence while the predicate is true.");
+ 
+ PyTypeObject takewhile_type = {
+ 	PyObject_HEAD_INIT(NULL)
+ 	0,				/* ob_size */
+ 	"itertools.takewhile",		 /* tp_name */
+ 	sizeof(takewhileobject),		 /* tp_basicsize */
+ 	0,				/* tp_itemsize */
+ 	/* methods */
+ 	(destructor)takewhile_dealloc,	   /* tp_dealloc */
+ 	0,				/* tp_print */
+ 	0,				/* tp_getattr */
+ 	0,				/* tp_setattr */
+ 	0,				/* tp_compare */
+ 	0,				/* tp_repr */
+ 	0,				/* tp_as_number */
+ 	0,				/* tp_as_sequence */
+ 	0,				/* tp_as_mapping */
+ 	0,				/* tp_hash */
+ 	0,				/* tp_call */
+ 	0,				/* tp_str */
+ 	PyObject_GenericGetAttr,	/* tp_getattro */
+ 	0,				/* tp_setattro */
+ 	0,				/* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+ 	takewhile_doc,			   /* tp_doc */
+ 	(traverseproc)takewhile_traverse,    /* tp_traverse */
+ 	0,				/* tp_clear */
+ 	0,				/* tp_richcompare */
+ 	0,				/* tp_weaklistoffset */
+ 	(getiterfunc)takewhile_getiter,	   /* tp_iter */
+ 	(iternextfunc)takewhile_next,	   /* tp_iternext */
+ 	0,				/* tp_methods */
+ 	0,				/* tp_members */
+ 	0,				/* tp_getset */
+ 	0,				/* tp_base */
+ 	0,				/* tp_dict */
+ 	0,				/* tp_descr_get */
+ 	0,				/* tp_descr_set */
+ 	0,				/* tp_dictoffset */
+ 	0,				/* tp_init */
+ 	PyType_GenericAlloc,		/* tp_alloc */
+ 	takewhile_new,			 /* tp_new */
+ 	PyObject_GC_Del,		/* tp_free */
+ };
+ 
+ 
  /* islice object ************************************************************/
  
***************
*** 1085,1089 ****
  Infinite iterators:\n\
  count([n]) --> n, n+1, n+2, ...\n\
- cycle(seq) --> seq0, seq1, ... seqlast, seq0, ...\n\
  repeat(elem) --> elem, elem, elem, elem\n\
  \n\
--- 1227,1230 ----
***************
*** 1097,1100 ****
--- 1238,1243 ----
  imap(fun, p, q) --> fun(p0, q0), fun(p1, q1), ...\n\
  starmap(fun, s) --> fun(*s[0]), fun(*s[1]), ...\n\
+ times(n) --> None, None, ... for n times.\n\
+ takewhile(pred, seq) --> s[0], s[1], until pred fails\n\
  ");
  
***************
*** 1105,1108 ****
--- 1248,1256 ----
  	PyObject *m;
  	m = Py_InitModule3("itertools", NULL, module_doc);
+ 
+ 	PyModule_AddObject(m, "takewhile", (PyObject *)&takewhile_type);
+ 	if (PyType_Ready(&takewhile_type) < 0)
+ 		return;
+ 	Py_INCREF(&takewhile_type);
  
  	PyModule_AddObject(m, "islice", (PyObject *)&islice_type);

Index: test_itertools.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/test_itertools.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** test_itertools.py	27 Jan 2003 10:03:06 -0000	1.4
--- test_itertools.py	27 Jan 2003 11:17:45 -0000	1.5
***************
*** 63,67 ****
              self.assertEqual(list(islice(xrange(100), *args)), range(*tgtargs))
  
- 
          self.assertRaises(TypeError, islice, xrange(10))
          self.assertRaises(TypeError, islice, xrange(10), 1, 2, 3, 4)
--- 63,66 ----
***************
*** 70,73 ****
--- 69,82 ----
          self.assertRaises(ValueError, islice, xrange(10), 1, 10, -1)
          self.assertRaises(ValueError, islice, xrange(10), 1, 10, 0)
+ 
+     def test_takewhile(self):
+         data = [1, 3, 5, 20, 2, 4, 6, 8]
+         underten = lambda x: x<10
+         self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
+ 
+ ##    def test_dropwhile(self):
+ ##        data = [1, 3, 5, 20, 2, 4, 6, 8]
+ ##        underten = lambda x: x<10
+ ##        self.assertEqual(list(takewhile(underten, data)), [20, 2, 4, 6, 8])     
  
  def test_main():

Index: todo.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/itertools/todo.txt,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** todo.txt	27 Jan 2003 10:44:52 -0000	1.7
--- todo.txt	27 Jan 2003 11:17:45 -0000	1.8
***************
*** 1,8 ****
  Add:
     iapply(func)  			?? what did this do in SML
-    takewhile(pred, seqn)
     dropwhile(pred, seqn)
     unzip(seqn)                          ?? does this make sense for iterators
!    exists() and any()                   ?? do these make sense
  
  
--- 1,7 ----
  Add:
     iapply(func)  			?? what did this do in SML
     dropwhile(pred, seqn)
     unzip(seqn)                          ?? does this make sense for iterators
!    exists() and any()                   ?? these don't return iterators