Commit | Line | Data |
---|---|---|
ae63d7db SBS |
1 | #!/usr/bin/env python3 |
2 | # Desc: Pauses a random amount of time. Random distribution is inverse gaussian. | |
a967b286 | 3 | # Version: 0.0.5 |
ae63d7db | 4 | # Depends: python 3.7.3 |
a967b286 | 5 | # Usage: ./sleepRand.py [-v] [-p P] SECONDS |
787f6bbd | 6 | # Input: SECONDS: float seconds (mean of inverse gaussian distribution) |
a967b286 | 7 | # P: precision (lambda of inverse gaussian distribution) |
787f6bbd | 8 | # Example: python3 sleepRand.py -vv -p 8.0 60.0 |
ae63d7db | 9 | |
787f6bbd SBS |
10 | import argparse; |
11 | import math, time, random, sys; | |
12 | import logging; | |
ae63d7db | 13 | |
787f6bbd SBS |
14 | # Set up argument parser (see https://docs.python.org/3.7/library/argparse.html ) |
15 | parser = argparse.ArgumentParser( | |
16 | description='Delay activity for a random number of seconds. Delays sampled from an inverse gaussian distribution.', | |
17 | epilog="Author: Steven Baltakatei Sandoval. License: GPLv3+"); | |
18 | parser.add_argument('-v','--verbose', | |
19 | action='count', | |
20 | dest='verbosity', | |
21 | default=0, | |
22 | help='Verbose output. (repeat for increased verbosity)'); | |
23 | parser.add_argument('mean', | |
24 | action='store', | |
25 | metavar='SECONDS', | |
26 | nargs=1, | |
27 | default=1, | |
28 | type=float, | |
29 | help='Mean seconds of delay. Is the mean of the inverse gaussian distribution.'); | |
30 | parser.add_argument('--precision','-p', | |
31 | action='store', | |
32 | metavar='P', | |
33 | nargs=1, | |
34 | default=[4.0], | |
35 | type=float, | |
36 | help='How concentrated delays are around the mean (default: 4.0). Must be a positive integer or floating point value. Is the lambda factor in the inverse gaussian distribution. High values (e.g. > 10.0) cause random delays to rarely stray far from MEAN. Small values (e.g. < 0.10) result in many small delays plus occasional long delays.'); | |
37 | args = parser.parse_args(); | |
0e82b3c2 | 38 | |
ae63d7db | 39 | # Define functions |
787f6bbd | 40 | def setup_logging(verbosity): |
a967b286 | 41 | '''Sets up logging''' |
787f6bbd SBS |
42 | # Depends: module: argparse |
43 | # Ref/Attrib: Haas, Florian; Configure logging with argparse; https://xahteiwi.eu/resources/hints-and-kinks/python-cli-logging-options/ | |
44 | base_loglevel = 30; | |
45 | verbosity = min(verbosity, 2); | |
46 | loglevel = base_loglevel - (verbosity * 10); | |
47 | logging.basicConfig(level=loglevel, | |
48 | format='%(message)s'); | |
49 | ||
ae63d7db SBS |
50 | def randInvGau(mu, lam): |
51 | """Returns random variate of inverse gaussian distribution""" | |
b914c401 SBS |
52 | # input: mu: mean of inverse gaussian distribution |
53 | # lam: shape parameter | |
54 | # output: float sampled from inv. gaus. with range 0 to infinity, mean mu | |
55 | # example: sample = float(randInvGau(1.0,4.0)); | |
787f6bbd | 56 | # Ref/Attrib: Michael, John R. "Generating Random Variates Using Transformations with Multiple Roots" https://doi.org/10.2307/2683801 |
ae63d7db SBS |
57 | nu = random.gauss(0,1); |
58 | y = nu ** 2; | |
59 | xTerm1 = mu; | |
60 | xTerm2 = mu ** 2 * y / (2 * lam); | |
61 | xTerm3 = (- mu / (2 * lam)) * math.sqrt(4 * mu * lam * y + mu ** 2 * y ** 2); | |
62 | x = xTerm1 + xTerm2 + xTerm3; | |
63 | z = random.uniform(0.0,1.0); | |
64 | if z <= (mu / (mu + x)): | |
65 | return x; | |
66 | else: | |
67 | return (mu ** 2 / x); | |
68 | ||
787f6bbd SBS |
69 | # Process input |
70 | ## Start up logger | |
71 | setup_logging(args.verbosity); | |
72 | logging.debug('DEBUG:Debug logging output enabled.'); | |
73 | logging.debug('DEBUG:args.verbosity:' + str(args.verbosity)); | |
74 | logging.debug('DEBUG:args:' + str(args)); | |
a967b286 | 75 | |
787f6bbd SBS |
76 | ## Reject negative floats. |
77 | try: | |
78 | ### Get desired mean | |
79 | desMean = args.mean[0]; | |
80 | logging.debug('DEBUG:Desired mean:' + str(desMean)); | |
81 | ### Get lambda precision factor | |
82 | lambdaFactor = args.precision[0]; | |
83 | logging.debug('DEBUG:Lambda precision factor:' + str(lambdaFactor)); | |
84 | if desMean < 0: | |
85 | logging.error('ERROR:Desired mean is negative:' + str(desMean)); | |
86 | raise ValueError('Negative number error.'); | |
87 | if lambdaFactor < 0: | |
88 | logging.error('ERROR:Lambda precision factor is negative:' + str(lambdaFactor)); | |
89 | raise ValueError('Negative number error.'); | |
90 | except ValueError: | |
91 | sys.exit(1); | |
ae63d7db | 92 | |
ae63d7db SBS |
93 | # Calculate delay |
94 | delay = randInvGau(desMean, desMean * lambdaFactor); | |
787f6bbd | 95 | logging.debug('delay:' + str(delay)); |
ae63d7db SBS |
96 | |
97 | # Sleep | |
98 | time.sleep(float(delay)); | |
99 | ||
b914c401 SBS |
100 | # Author: Steven Baltakatei Sandoal |
101 | # License: GPLv3+ |