Issue 1:
Original ticket http://projects.scipy.org/scipy/ticket/202 on 2006-05-07 by trac user nodwell@..., assigned to unknown.

I've made a small modification to import_array.py so that I can parse

a string as if it were a file. For my own purposes I needed to parse

web form input.

For example:

B = """# comment line

... 3 4 5

... 2 1 5"""

io.read_array(B, datainstring=1)

array([[ 3., 4., 5.],

[ 2., 1., 5.]])

Here is the diff to array_import.py

(there doesn't seem to be a way to attach files to a trac ticket)

--- /sw/lib/python2.4/site-packages/scipy/io/array_import.py 2006-03-17 04:43:52.000000000 -0800

+++ array_import.py 2006-05-07 13:11:22.000000000 -0700

@@ -3,7 +3,7 @@

"""This module allows for the loading of an array from an ASCII

-Text File

+Text File or a String object.

"""

@@ -25,6 +25,8 @@

Written by Travis Oliphant and Trent Oliphant

with support from Agilent, Inc.

+# Modified by Eric Nodwell to allow input from a string as well as a file.

+#

import os, sys

@@ -98,7 +100,7 @@

return file

-class ascii_stream:

+class ascii_stream_from_file :

"""Text files with line iteration

Ascii_stream instances can be used like normal read-only file objects

@@ -108,17 +110,14 @@

Finally, ascii_stream objects accept file names that start with '~' or

'~user' to indicate a home directory(for reading only).

Constructor: ascii_stream(|fileobject|, |lines|,|comment|),

Constructor: ascii_stream(|fileobject|, |lines|,|comment|, |linesep|),

where |fileobject| is either an open python file object or

the name of the file, |lines| is a sequence of integers

or tuples(indicating ranges) of lines to be read, |comment| is the

comment line identifier """

def init(self, fileobject, lines=default, comment="#",

linesep='\n'):

if not isinstance(comment, types.StringType):

raise ValueError, "Comment must be a string."

self.linelist = build_numberlist(lines)

def init(self, fileobject, linelist, comment, linesep):

self.linelist = linelist
self.comment = comment
self.lencomment = len(comment)
self.file = get_open_file(fileobject, mode='r')

@@ -183,6 +182,112 @@

self.file.flush()

+class ascii_stream_from_string :

"""Line iteration of a string.

Mimics ascii_stream_from_file, even where not strictly necessary

for input from a string.

Ascii_stream instances can be used like normal read-only file objects

(i.e. by calling readline() and readlines()), but can

also be used as sequences of lines in for-loops.

Constructor: ascii_stream(|fileobject|, |lines|,|comment|, |linesep|),

where |fileobject| is either an open python file object or

the name of the file, |lines| is a sequence of integers

or tuples(indicating ranges) of lines to be read, |comment| is the

comment line identifier """

def init(self, stringobject, linelist, comment, linesep):

self._string = stringobject

self.linelist = linelist

self.comment = comment

self.lencomment = len(comment)

self._lineindex = 0

if self.linelist[-1] < 0:

self._linetoget = self.linelist[-1]

else:

self._linetoget = 0

self._linesplitter = linesep

self._buffer = self._string.split(self._linesplitter)

def readlines(self, sizehint):

return self._buffer

def getitem(self, item):

while 1:

line = self.readnextline()

if line is None:

raise IndexError

if len(line) < self.lencomment or line[:self.lencomment] != self.comment:

break

return line

def readnextline(self):

if self.linelist[self._lineindex] >= 0:

self._linetoget = self.linelist[self._lineindex]

self._lineindex += 1

else:

self._linetoget = self._linetoget - self.linelist[self._lineindex]

if self._linetoget >= len(self._buffer):

return None

line = self._buffer[self._linetoget]

return line

def close(self):

pass

def flush(self):

pass

+class ascii_stream :

"""Text files or string input with line iteration

Ascii_stream instances can be used like normal read-only file objects

(i.e. by calling readline() and readlines()), but can

also be used as sequences of lines in for-loops.

Ascii_stream objects accept file names that start with '~' or

'~user' to indicate a home directory(for reading only).. If

|datainstring| is true, then instead of reading lines from a file,

|fileobject| is taken as a string from which lines are read.

Constructor: ascii_stream(|fileobject|, |lines|,|comment|,

|linesep|, |datainstring|),

where |fileobject| is either an open python file object or

the name of the file, |lines| is a sequence of integers

or tuples(indicating ranges) of lines to be read, |comment| is the

comment line identifier """

def init(self, fileobject, lines=default, comment="#",

linesep='\n', datainstring=0):

if not isinstance(comment, types.StringType):

raise ValueError, "Comment must be a string."

self.linelist = build_numberlist(lines)

self.comment = comment

self.lencomment = len(comment)

if datainstring:

self._stream = ascii_stream_from_string (fileobject, self.linelist,

comment, linesep)

else:

self._stream = ascii_stream_from_file (fileobject, self.linelist,

comment, linesep)

self._buffer = self._stream._buffer

def readlines(self, sizehint):

return self._stream.readlines(sizehint)

def getitem(self, item):

return self._stream.__getitem__(item)

def close(self):

self._stream.close()

def flush(self):

self._stream.flush()

def move_past_spaces(firstline):

ind = 0

firstline = firstline.lstrip()

@@ -295,13 +400,14 @@

def read_array(fileobject, separator=default, columns=default, comment="#",

lines=default, atype=numpy.Float, linesep='\n',

rowsize=10000, missing=0):

rowsize=10000, missing=0, datainstring=0):

"""Return an array or arrays from ascii_formatted data in |fileobject|.

Inputs:

fileobject -- An open file object or a string for a valid filename.

The string can be prepended by "~/" or "~<name>/" to

fileobject -- An open file object or a string for a valid filename

or a string to be parsed (if datainstring is nonzero).

A file name can be prepended by "~/" or "~<name>/" to
read a file from the home directory.

separator -- a string or a tuple of strings to indicate the column

separators. If the length of the string tuple is less

@@ -330,6 +436,8 @@

copying the last entry.

rowsize -- the allocation row size (array grows by this amount as

data is read in).

datainstring -- if nonzero, interpet fileobject as containing the

data to be read in.

Output -- the 1 or 2d array, or a tuple of output arrays of different

types, sorted in order of the first column to be placed

@@ -344,7 +452,8 @@

else:

sep = tuple(separator)

Create ascii_object from |fileobject| argument.

ascii_object = ascii_stream(fileobject, lines=lines, comment=comment, linesep=linesep)

ascii_object = ascii_stream(fileobject, lines=lines, comment=comment,

linesep=linesep, datainstring=datainstring)

columns, atype = convert_to_equal_lists(columns, atype)

numout = len(atype)

Get the number of columns to read and expand the columns argument

Issue 2:
Original ticket http://projects.scipy.org/scipy/ticket/1688 on 2012-07-05 by trac user jokahn, assigned to unknown.

binomial and scipy.stats.binom are not defined for n=0, raising a value error.

For example

[[BR]]

binomial(0, .3)

[[BR]]

or

[[BR]]

scipy.stats.binom.rvs(arange(5),.3)

[[BR]]

will fail.

The binomial distribution is perfectly well-defined in this case: it is merely the Dirac at zero. Therefore a function implementing this random variable should not fail in this case.

Add to that the fact that a typical use of the function would be thinning data on many entries, where some might be zero, and it's also a practical concern.