Repository: scipy/scipy

Issue:
DOC: Problem with the randint description
### Issue with current documentation:

In the randint page https://scipy.github.io/devdocs/reference/generated/scipy.stats.randint.html

it is said that the index k can go from [low to high-1] (both included), so in that example from 7 to 30. The PMF values are calculated and shown correctly, but the generated k values are missing the value 30, i.e. only k values from 7 to 29 are generated and shown in the plot, when the value 30 should also be included.

### Idea or request for content:

One solution would be to change
`x = np.arange(randint.ppf(0.01, low, high),randint.ppf(0.99, low, high))`
for
`x = np.arange(low,high)`

### Additional context (e.g. screenshots, GIFs)

_No response_


Discussion:
Yes, that would be a good fix. The `ppf(0.1, ...)` stuff is copy-pasted from other distributions that have infinite support. But maybe `x = np.arange(low - 5, high + 5)` to show that there are 0s outside of the range.
Yes, that sounds good. There are other instances where the usage of the ppf method to generate the k values can fail, I have seen this too with the binomial distribution.

https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binom.html
@pepCV would you like to make a PR to fix it?
Yes, I can do that! One question though, I see in the code

https://github.com/scipy/scipy/blob/main/scipy/stats/_discrete_distns.py#L1054

where is this example string stored, in which file can I see it and modify it? Thanks!
> Yes, I can do that! One question though, I see in the code
> 
> https://github.com/scipy/scipy/blob/main/scipy/stats/_discrete_distns.py#L1054
> 
> where is this example string stored, in which file can I see it and modify it? Thanks!

Thanks for your interest in a PR! :) I think it comes from [here](https://github.com/scipy/scipy/blob/e1f0d9717a20919cc55d947a46edda9942748b93/scipy/stats/_distn_infrastructure.py#L293)
@pepCV thought I'd check in - when should we look out for that PR?
I started looking at this, struggling to understand where the string substitutions are defined?
In the `randint_gen` docstring, there is a line [`%(example)s`](https://github.com/scipy/scipy/blob/e1f0d9717a20919cc55d947a46edda9942748b93/scipy/stats/_discrete_distns.py#L1054) which is where the generic `Examples` section is inserted. Remove that line and write your own `Examples` section there instead. [`hypergeom_gen`](https://github.com/scipy/scipy/blob/e1f0d9717a20919cc55d947a46edda9942748b93/scipy/stats/_discrete_distns.py#L479-L511) is another distribution that has its own non-generic `Examples` section, for reference.
Thanks, I was trying to see if there was a way to preserve the reference to the generic documentation. Doesn't matter.

Resolving patch:
diff --git a/scipy/stats/_discrete_distns.py b/scipy/stats/_discrete_distns.py
--- a/scipy/stats/_discrete_distns.py
+++ b/scipy/stats/_discrete_distns.py
@@ -1051,7 +1051,47 @@ class randint_gen(rv_discrete):
 
     %(after_notes)s
 
-    %(example)s
+    Examples
+    --------
+    >>> import numpy as np
+    >>> from scipy.stats import randint
+    >>> import matplotlib.pyplot as plt
+    >>> fig, ax = plt.subplots(1, 1)
+
+    Calculate the first four moments:
+
+    >>> low, high = 7, 31
+    >>> mean, var, skew, kurt = randint.stats(low, high, moments='mvsk')
+
+    Display the probability mass function (``pmf``):
+
+    >>> x = np.arange(low - 5, high + 5)
+    >>> ax.plot(x, randint.pmf(x, low, high), 'bo', ms=8, label='randint pmf')
+    >>> ax.vlines(x, 0, randint.pmf(x, low, high), colors='b', lw=5, alpha=0.5)
+    
+    Alternatively, the distribution object can be called (as a function) to 
+    fix the shape and location. This returns a "frozen" RV object holding the
+    given parameters fixed.
+
+    Freeze the distribution and display the frozen ``pmf``:
+
+    >>> rv = randint(low, high)
+    >>> ax.vlines(x, 0, rv.pmf(x), colors='k', linestyles='-',
+    ...           lw=1, label='frozen pmf')
+    >>> ax.legend(loc='lower center')
+    >>> plt.show()
+    
+    Check the relationship between the cumulative distribution function
+    (``cdf``) and its inverse, the percent point function (``ppf``):
+
+    >>> q = np.arange(low, high)
+    >>> p = randint.cdf(q, low, high)
+    >>> np.allclose(q, randint.ppf(p, low, high))
+    True
+
+    Generate random numbers:
+
+    >>> r = randint.rvs(low, high, size=1000)
 
     """
 


Test patch: