diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c8e4894 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.lock \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..898e9eb --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ + + +# README + +## Random Lottery Number Generator + +This Python program generates lottery numbers using random entropy, statistical analysis, and Z-score-based cluster detection. It identifies clusters in a dataset to select attractor points, which are then scaled and presented as lottery numbers. + +--- + +## Features + +- Generates random data using Randonautica's quantum random number generator. +- Identifies clusters of numbers as attractors quantified by z-scores. +- Draws main lottery numbers and a bonus ball (Mega Millions). +- Provides a progress bar and rich console output. +- Fully configurable with user inputs for lottery size and z-score thresholds. + +--- + +## Installation + +### Prerequisites + +- Python 3.12 or later +- `pipenv` for dependency management + +### Setup + +1. Clone the repository and navigate to its directory. +2. Install dependencies using `pipenv`: + ```bash + pipenv install + ``` +3. Activate the virtual environment: + ```bash + pipenv shell + ``` + +--- + +## Usage + +Run the program with the following command: + +```bash +python main.py +``` + +### Configuration Prompts + +- **Number of Balls to Draw**: Total numbers in the main lottery draw (default: 5). +- **Range of Lottery Numbers**: Maximum number in the main lottery (default: 70). +- **Range of Bonus Ball**: Maximum number for the bonus ball (default: 25). +- **Minimum Z-Score Threshold**: Threshold for identifying attractor clusters (default: 3.0). Below 2.0 it is statistically insignificant. Above 4.0 it is highly anomalous. Pick something between 2.0 and 4.0. \ No newline at end of file diff --git a/main.py b/main.py index 6da3a95..7842277 100644 --- a/main.py +++ b/main.py @@ -6,11 +6,13 @@ from rich.console import Console from rich.text import Text from rich.progress import Progress, TextColumn, BarColumn -# Validate if a string can be converted to a float -def can_be_float(s): +# Validate Z-Score +def z_thresh(s): try: - float(s) - return True + if float(s) >= 1.0 and float(s) <= 5.0: + return True + else: + return False except ValueError: return False @@ -62,9 +64,12 @@ def pull_number(numbers: set, top: int, amount: int, z_score: float): # Main function to drive the lottery draw process def main(): + console = Console() + # Display an introduction to the lottery process - console.print("\nEach lottery ball is selected by analyzing random values.\n", style="italic green") + description = "\nEach lottery ball is selected by generating hundreds of random values within the provided range. The data is analyzed to identify number clusters. The centroid values of the attractor clusters with a z-score above the set threshold are selected as lotto numbers. This process repeats until all balls are drawn. The entire method is a one-dimensional analogy to how attractor points are calculated in Randonautica.\n" + console.print(description, style="italic green") # Get the number of lottery balls to draw num_lotto_balls = int(questionary.text( @@ -89,9 +94,9 @@ def main(): # Get the Z-score threshold for anomaly detection z_score_threshold = float(questionary.text( - "Minimum Z-Score Threshold? (default: 4.0)", - validate=lambda val: can_be_float(val) or "Please enter a valid value (1.0 - 5.0).", - default="4.0" + "Minimum Z-Score Threshold? (default: 3.0)", + validate=lambda val: z_thresh(val) or "Please enter a valid value (1.0 - 5.0).", + default="3.0" ).ask()) numbers = set()