Skip to content

Commit

Permalink
Merge pull request #6 from sbalian/misc-improvements
Browse files Browse the repository at this point in the history
Misc improvements
  • Loading branch information
sbalian committed Apr 4, 2023
2 parents fe44651 + cecea88 commit d0fcdd3
Show file tree
Hide file tree
Showing 31 changed files with 1,163 additions and 1,764 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Upload Python Package

on:
release:
types: [published]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
86 changes: 54 additions & 32 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,46 +1,68 @@
name: Tests
name: Testing, type checking and linting

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
on: [push]

jobs:
python:

runs-on: ubuntu-latest
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Prepare
run: |
python -m pip install --upgrade pip
pip install tox
- name: Run tests
run: |
tox -e py
test-numpy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
exclude:
- os: macos-latest
python-version: '3.11'
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install
- name: Prepare
run: |
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py > get-poetry.py
python get-poetry.py -y
rm get-poetry.py
source $HOME/.poetry/env
poetry install
poetry install -E numpy
poetry install -E analysis
- name: Build
python -m pip install --upgrade pip
pip install tox
- name: Run tests
run: |
source $HOME/.poetry/env
poetry build
- name: Lint
tox -e numpy
- name: Check types
run: |
source $HOME/.poetry/env
poetry run isort . --check-only
poetry run black --check .
poetry run flake8 .
poetry run mypy qrandom
- name: Test
mkdir .mypy_cache
tox -e mypy
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Prepare
run: |
python -m pip install --upgrade pip
pip install tox
- name: Lint
run: |
source $HOME/.poetry/env
QRANDOM_API_KEY=key poetry run pytest
tox -e flake8,black,isort
8 changes: 3 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
*.pyc
dist/
.mypy_cache/
.pytest_cache/
__pycache__/
.tox/
.python-version
dist/
*.egg-info/
TODO
src/qrandom/version.py
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2022 Seto Balian
Copyright 2023 Seto Balian

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
Expand Down
122 changes: 61 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,18 @@
# Quantum random numbers in Python

![Tests](https://github.com/sbalian/quantum-random/workflows/Tests/badge.svg)
[![Version](https://img.shields.io/pypi/v/quantum-random)](https://pypi.org/project/quantum-random/)
![Python Versions](https://img.shields.io/pypi/pyversions/quantum-random)
[![Download Stats](https://img.shields.io/pypi/dm/quantum-random)](https://pypistats.org/packages/quantum-random)
![License](https://img.shields.io/github/license/sbalian/quantum-random)

This package brings the [ANU quantum random numbers][anu] to Python 3.7 to 3.10.

The default pseudo-random generator in Python is replaced by calls to the
ANU API that serves real quantum random numbers.

## Install

```bash
pip install quantum-random
```

Optionally, for [NumPy][numpy] support,

```bash
pip install quantum-random[numpy]
```

Note that the NumPy integration is not well-tested and is only available
for Python 3.8 and 3.9.

## Setup: passing your API key

ANU now requires you to use an API key. You can get a free (trial) or paid key
from [here][anupricing].

You can pass your key to `qrandom` in three ways:

1. By setting the environment variable `QRANDOM_API_KEY`.
2. By running `qrandom-init` to save your key in an INI config file that is
stored in a subdirectory of your default home config directory (as specified
by XDG, e.g., `/home/<your-username>/.config/qrandom/`).
3. By running `qrandom-init` to save your key in an INI file in a directory
of your choice set by `QRANDOM_CONFIG_DIR`.

`qrandom` will look for the key in the order above. The `qrandom-init` utility
is interactive and comes installed with `qrandom`.
Use the [Python random module][pyrandom] with real quantum random numbers from
[ANU][anu]. The default pseudo-random generator is replaced by calls to
the ANU API.

## Usage

Just import `qrandom` and use it like you'd use the
[standard Python random module][pyrandom]. For example,
Import `qrandom` and use it like the standard `random` module. For example:

```python
>>> import qrandom
Expand All @@ -57,14 +27,10 @@ Just import `qrandom` and use it like you'd use the
-0.8370871276247828
```

Alternatively, you can `import QuantumRandom from qrandom` and use the class
directly (just like `random.Random`).
Alternatively, you can use the class `qrandom.QuantumRandom`. It has the same
interface as `random.Random`.

Under the hood, batches of quantum numbers are fetched from the API as needed
and each batch contains 1024 numbers. If you wish to pre-fetch more, use
`qrandom.fill(n)`, where `n` is the number of batches.

Optionally, if you have installed the NumPy integration,
There is also a [NumPy][numpy] interface, although it is not fully tested:

```python
>>> from qrandom.numpy import quantum_rng
Expand All @@ -77,42 +43,76 @@ array([[0.37220278, 0.24337193, 0.67534826],
[0.35894084, 0.72219929, 0.55388594]])
```

## Tests
NumPy is supported using [RandomGen][randomgen]. Note that there are currently
no RandomGen wheels available for Python 3.11.

To run the tests locally, you will need [poetry][poetry] and Python 3.7-3.10
(i.e., multiple versions of Python installed and seen by tox using, for example,
[pyenv][pyenv]). Then,
## Installation

The minimum supported Python version is 3.7. Install with `pip`:

```bash
python -m pip install -U quantum-random
```

If you want NumPy support:

```bash
poetry install
poetry run tox
python -m pip install -U quantum-random[numpy]
```

See [here](./docs/uniform.md) for a visualisation and a Kolmogorov–Smirnov test.
## First-time setup: setting your API key

ANU requires you to use an API key. You can get a free trial or pay for a key
[here][anupricing].

You can pass your key to `qrandom` in three ways:

1. By setting the environment variable `QRANDOM_API_KEY`.
2. By running `qrandom-init` to save your key in an INI file
stored in a subdirectory of your home config directory as specified
by XDG, e.g., `/home/<your-username>/.config/qrandom/`.
3. By running `qrandom-init` to save your key in an INI file in a directory
of your choice set by `QRANDOM_CONFIG_DIR`.

`qrandom` will look for the key in the order above. The `qrandom-init`
command line utility is installed as part of the package.

## Pre-fetching batches

Batches of quantum numbers are fetched from the API as needed.
Each batch contains 1024 numbers. Use `qrandom.fill(n)` to fetch `n` batches
if you need to pre-fetch at the start of your computation.

## Tests

The tests run for Python 3.7 - 3.11 on the latest Windows,
macOS and Ubuntu runner images. For Python 3.11 on macOS, the tests run
only with no NumPy support as RandomGen fails to compile. Use [tox][tox] to run
the tests locally.

See [here](./analysis/uniform.md) for a visualisation and a Kolmogorov–Smirnov
test.

## Notes on implementation

The `qrandom` module exposes a class derived from `random.Random` with a
`random()` method that outputs quantum floats in the range [0, 1)
(converted from 64-bit ints). Overriding `random.Random.random`
(converted from 64-bit integers). Overriding `random.Random.random`
is sufficient to make the `qrandom` module behave mostly like the
`random` module as described in the [Python docs][pyrandom]. The exceptions
at the moment are `getrandbits()` and `randbytes()` that are not available in
are `getrandbits()` and `randbytes()`: these are not available in
`qrandom`. Because `getrandbits()` is not available, `randrange()` cannot
produce arbitrarily long sequences. Finally, the user is warned when `seed()`
is called because there is no state. For the same reason, `getstate()` and
`setstate()` are not implemented.

NumPy support is provided using [RandomGen][randomgen].
is called because the quantum generator has no state. For the same reason,
`getstate()` and `setstate()` are not implemented.

## License

See [LICENCE](./LICENSE).

[anu]: https://quantumnumbers.anu.edu.au
[anupricing]: https://quantumnumbers.anu.edu.au/pricing
[pyrandom]: https://docs.python.org/3.9/library/random.html
[poetry]: https://python-poetry.org
[pyenv]: https://github.com/pyenv/pyenv
[pyrandom]: https://docs.python.org/3/library/random.html
[tox]: https://tox.wiki/en/latest/
[numpy]: https://numpy.org
[randomgen]: https://github.com/bashtage/randomgen
15 changes: 15 additions & 0 deletions analysis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Analysis

To run the analysis, first install the requirements (includes `quantum-random`):

```bash
pip install -r requirements.txt
```

Then run the script to generate the plot in `uniform.md`:

```bash
python generate_plot.py
```

The output is written to `random.png`.
24 changes: 9 additions & 15 deletions docs/generate_plot.py → analysis/generate_plot.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import random
import sys

try:
import matplotlib.pyplot as plt
from scipy import stats
except ModuleNotFoundError:
print(
"To run this script, install with `poetry install -E analysis`."
"Only Python 3.8 and 3.9 are supported."
)
sys.exit(1)
from typing import List, Tuple

import matplotlib.pyplot as plt
from scipy import stats

import qrandom

DataType = Tuple[Tuple[List[float], str], Tuple[List[float], str]]


def generate_data():
def generate_data() -> DataType:
numbers = [qrandom.random() for _ in range(10000)]
py_numbers = [random.random() for _ in range(10000)]
return (numbers, "Quantum random"), (py_numbers, "Python pseudo-random")


def plot(data):
def plot(data: DataType) -> None:
quantum, python = data
numbers, quantum_title = quantum
py_numbers, python_title = python
Expand All @@ -38,7 +32,7 @@ def plot(data):
return


def kstest(data):
def kstest(data: DataType) -> None:
quantum, python = data
numbers, quantum_title = quantum
py_numbers, python_title = python
Expand All @@ -48,7 +42,7 @@ def kstest(data):
return


def main():
def main() -> None:
data = generate_data()
plot(data)
kstest(data)
Expand Down
Binary file added analysis/random.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions analysis/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
scipy
matplotlib
quantum-random
Loading

0 comments on commit d0fcdd3

Please sign in to comment.