Commit | Line | Data |
---|---|---|
ae63d7db SBS |
1 | #!/usr/bin/env python3 |
2 | # Desc: Pauses a random amount of time. Random distribution is inverse gaussian. | |
787f6bbd | 3 | # Version: 0.0.4 |
ae63d7db | 4 | # Depends: python 3.7.3 |
787f6bbd SBS |
5 | # Usage: ./sleepRand.py [-v] [-p L] SECONDS |
6 | # Input: SECONDS: float seconds (mean of inverse gaussian distribution) | |
7 | # L: precision (lambda of inverse gaussian distribution) | |
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 SBS |
40 | def setup_logging(verbosity): |
41 | # Depends: module: argparse | |
42 | # Ref/Attrib: Haas, Florian; Configure logging with argparse; https://xahteiwi.eu/resources/hints-and-kinks/python-cli-logging-options/ | |
43 | base_loglevel = 30; | |
44 | verbosity = min(verbosity, 2); | |
45 | loglevel = base_loglevel - (verbosity * 10); | |
46 | logging.basicConfig(level=loglevel, | |
47 | format='%(message)s'); | |
48 | ||
ae63d7db SBS |
49 | def randInvGau(mu, lam): |
50 | """Returns random variate of inverse gaussian distribution""" | |
b914c401 SBS |
51 | # input: mu: mean of inverse gaussian distribution |
52 | # lam: shape parameter | |
53 | # output: float sampled from inv. gaus. with range 0 to infinity, mean mu | |
54 | # example: sample = float(randInvGau(1.0,4.0)); | |
787f6bbd | 55 | # Ref/Attrib: Michael, John R. "Generating Random Variates Using Transformations with Multiple Roots" https://doi.org/10.2307/2683801 |
ae63d7db SBS |
56 | nu = random.gauss(0,1); |
57 | y = nu ** 2; | |
58 | xTerm1 = mu; | |
59 | xTerm2 = mu ** 2 * y / (2 * lam); | |
60 | xTerm3 = (- mu / (2 * lam)) * math.sqrt(4 * mu * lam * y + mu ** 2 * y ** 2); | |
61 | x = xTerm1 + xTerm2 + xTerm3; | |
62 | z = random.uniform(0.0,1.0); | |
63 | if z <= (mu / (mu + x)): | |
64 | return x; | |
65 | else: | |
66 | return (mu ** 2 / x); | |
67 | ||
787f6bbd SBS |
68 | # Process input |
69 | ## Start up logger | |
70 | setup_logging(args.verbosity); | |
71 | logging.debug('DEBUG:Debug logging output enabled.'); | |
72 | logging.debug('DEBUG:args.verbosity:' + str(args.verbosity)); | |
73 | logging.debug('DEBUG:args:' + str(args)); | |
74 | ## Reject negative floats. | |
75 | try: | |
76 | ### Get desired mean | |
77 | desMean = args.mean[0]; | |
78 | logging.debug('DEBUG:Desired mean:' + str(desMean)); | |
79 | ### Get lambda precision factor | |
80 | lambdaFactor = args.precision[0]; | |
81 | logging.debug('DEBUG:Lambda precision factor:' + str(lambdaFactor)); | |
82 | if desMean < 0: | |
83 | logging.error('ERROR:Desired mean is negative:' + str(desMean)); | |
84 | raise ValueError('Negative number error.'); | |
85 | if lambdaFactor < 0: | |
86 | logging.error('ERROR:Lambda precision factor is negative:' + str(lambdaFactor)); | |
87 | raise ValueError('Negative number error.'); | |
88 | except ValueError: | |
89 | sys.exit(1); | |
ae63d7db | 90 | |
ae63d7db SBS |
91 | # Calculate delay |
92 | delay = randInvGau(desMean, desMean * lambdaFactor); | |
787f6bbd | 93 | logging.debug('delay:' + str(delay)); |
ae63d7db SBS |
94 | |
95 | # Sleep | |
96 | time.sleep(float(delay)); | |
97 | ||
b914c401 SBS |
98 | # Author: Steven Baltakatei Sandoal |
99 | # License: GPLv3+ |