salabim 24.0.13__py3-none-any.whl → 24.0.14.post3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
salabim/salabim.py CHANGED
@@ -1,13 +1,13 @@
1
- # _ _ _ ____ _ _ ___ _ _____
2
- # ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / ||___ /
3
- # / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | | |_ \
4
- # \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | | ___) |
5
- # |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_||____/
1
+ # _ _ _ ____ _ _ ___ _ _ _
2
+ # ___ __ _ | | __ _ | |__ (_) _ __ ___ |___ \ | || | / _ \ / || || |
3
+ # / __| / _` || | / _` || '_ \ | || '_ ` _ \ __) || || |_ | | | | | || || |_
4
+ # \__ \| (_| || || (_| || |_) || || | | | | | / __/ |__ _| _ | |_| | _ | ||__ _|
5
+ # |___/ \__,_||_| \__,_||_.__/ |_||_| |_| |_| |_____| |_| (_) \___/ (_)|_| |_|
6
6
  # discrete event simulation
7
7
  #
8
8
  # see www.salabim.org for more information, the documentation and license information
9
9
 
10
- __version__ = "24.0.13"
10
+ __version__ = "24.0.14"
11
11
 
12
12
  import heapq
13
13
  import random
@@ -9055,7 +9055,6 @@ by adding:
9055
9055
  else:
9056
9056
  return
9057
9057
 
9058
-
9059
9058
  def _trywait(self):
9060
9059
  if self.status.value == interrupted:
9061
9060
  return False
@@ -10207,7 +10206,7 @@ class Event(Component):
10207
10206
  """
10208
10207
  return self._action_taken
10209
10208
 
10210
-
10209
+
10211
10210
  class Environment:
10212
10211
  """
10213
10212
  environment object
@@ -11349,13 +11348,13 @@ class Environment:
11349
11348
 
11350
11349
  if width is not None:
11351
11350
  if self._width != width:
11352
- self._width = width
11351
+ self._width = int(width)
11353
11352
  frame_changed = True
11354
11353
  width_changed = True
11355
11354
 
11356
11355
  if height is not None:
11357
11356
  if self._height != height:
11358
- self._height = height
11357
+ self._height = int(height)
11359
11358
  frame_changed = True
11360
11359
  height_changed = True
11361
11360
 
@@ -11804,7 +11803,8 @@ class Environment:
11804
11803
  for ao in an_objects:
11805
11804
  ao.make_pil_image(self.t())
11806
11805
  if ao._image_visible and (include_topleft or not ao.getattr("in_topleft", False)):
11807
- image.paste(ao._image, (int(ao._image_x), int(self._height - ao._image_y - ao._image.size[1])), ao._image)
11806
+ image.paste(ao._image, (int(ao._image_x), int(self._height - ao._image_y - ao._image.size[1])),ao._image.convert("RGBA"),)
11807
+
11808
11808
 
11809
11809
  return image.convert(mode)
11810
11810
 
@@ -13201,7 +13201,7 @@ class Environment:
13201
13201
  if co is None:
13202
13202
  if len(g.canvas_objects) >= self._maximum_number_of_bitmaps:
13203
13203
  if overflow_image is None:
13204
- overflow_image = Image.new("RGBA", (self._width, self._height), (0, 0, 0, 0))
13204
+ overflow_image = Image.new("RGBA", (int(self._width), int(self._height)), (0, 0, 0, 0))
13205
13205
  overflow_image.paste(ao._image, (int(ao._image_x), int(self._height - ao._image_y - ao._image.size[1])), ao._image)
13206
13206
  ao.canvas_object = None
13207
13207
  else:
@@ -15426,10 +15426,20 @@ class Animate2dBase(DynamicClass):
15426
15426
  spec = self.image(t)
15427
15427
  image_container = ImageContainer(spec)
15428
15428
  width = self.width(t)
15429
+ height = self.height(t)
15430
+
15429
15431
  if width is None:
15430
- width = image_container.images[0].size[0]
15432
+ if height is None:
15433
+ width = image_container.images[0].size[0]
15434
+ height = image_container.images[0].size[1]
15435
+ else:
15436
+ width = height * image_container.images[0].size[0] / image_container.images[0].size[1]
15437
+ else:
15438
+ if height is None:
15439
+ height = width * image_container.images[0].size[1] / image_container.images[0].size[0]
15440
+ else:
15441
+ ...
15431
15442
 
15432
- height = width * image_container.images[0].size[1] / image_container.images[0].size[0]
15433
15443
  if not self.screen_coordinates:
15434
15444
  width *= self.env._scale
15435
15445
  height *= self.env._scale
@@ -15448,7 +15458,6 @@ class Animate2dBase(DynamicClass):
15448
15458
  offsety = offsety * self.env._scale
15449
15459
 
15450
15460
  alpha = int(self.alpha(t))
15451
-
15452
15461
  image, id = image_container.get_image(
15453
15462
  (t - self.animation_start(t)) * self.animation_speed(t),
15454
15463
  repeat=self.animation_repeat(t),
@@ -15456,6 +15465,7 @@ class Animate2dBase(DynamicClass):
15456
15465
  t_from=self.animation_from(t),
15457
15466
  t_to=self.animation_to(t),
15458
15467
  )
15468
+
15459
15469
  self._image_ident = (spec, id, width, height, angle, alpha, flip_horizontal, flip_vertical)
15460
15470
 
15461
15471
  if self._image_ident != self._image_ident_prev:
@@ -15736,6 +15746,9 @@ class AnimateClassic(Animate2dBase):
15736
15746
  def width(self, t):
15737
15747
  return self.master.width(t)
15738
15748
 
15749
+ def height(self, t):
15750
+ return self.master.height(t)
15751
+
15739
15752
  def anchor(self, t):
15740
15753
  return self.master.anchor(t)
15741
15754
 
@@ -15963,6 +15976,11 @@ class Animate:
15963
15976
 
15964
15977
  if omitted or None, no scaling
15965
15978
 
15979
+ height0 : float
15980
+ width of the image to be displayed at time t0
15981
+
15982
+ if omitted or None, no scaling
15983
+
15966
15984
  t1 : float
15967
15985
  time of end of the animation (default inf)
15968
15986
 
@@ -16031,6 +16049,9 @@ class Animate:
16031
16049
  width1 : float
16032
16050
  width of the image to be displayed at time t1 (default: width0)
16033
16051
 
16052
+ height1 : float
16053
+ width of the image to be displayed at time t1 (default: height0)
16054
+
16034
16055
  over3d : bool
16035
16056
  if True, this object will be rendered to the OpenGL window
16036
16057
 
@@ -16099,6 +16120,7 @@ class Animate:
16099
16120
  font -
16100
16121
  fontsize0,fontsize1 -
16101
16122
  width0,width1 -
16123
+ height0,height1 -
16102
16124
  ====================== ========= ========= ========= ========= ========= =========
16103
16125
  """
16104
16126
 
@@ -16134,6 +16156,7 @@ class Animate:
16134
16156
  alpha0: float = 255,
16135
16157
  fontsize0: float = 20,
16136
16158
  width0: float = None,
16159
+ height0: float = None,
16137
16160
  t1: float = None,
16138
16161
  x1: float = None,
16139
16162
  y1: float = None,
@@ -16152,6 +16175,7 @@ class Animate:
16152
16175
  alpha1: float = None,
16153
16176
  fontsize1: float = None,
16154
16177
  width1: float = None,
16178
+ height1: float = None,
16155
16179
  xy_anchor: str = "",
16156
16180
  over3d: bool = None,
16157
16181
  flip_horizontal: bool = False,
@@ -16198,10 +16222,12 @@ class Animate:
16198
16222
  self.text0 = text
16199
16223
 
16200
16224
  if image is None:
16201
- self.width0 = 0 # just to be able to interpolate
16225
+ self.width0 = 0 # just to be able to interpolat
16226
+ self.height0 = 0
16202
16227
  else:
16203
16228
  self.image0 = image
16204
16229
  self.width0 = width0 # None means original size
16230
+ self.height0 = height0
16205
16231
 
16206
16232
  self.as_points0 = as_points
16207
16233
  self.font0 = font
@@ -16263,7 +16289,7 @@ class Animate:
16263
16289
  self.alpha1 = self.alpha0 if alpha1 is None else alpha1
16264
16290
  self.fontsize1 = self.fontsize0 if fontsize1 is None else fontsize1
16265
16291
  self.width1 = self.width0 if width1 is None else width1
16266
-
16292
+ self.height1 = self.height0 if height1 is None else height1
16267
16293
  self.t1 = inf if t1 is None else t1
16268
16294
  if self.env._animate_debug:
16269
16295
  self.caller = self.env._frame_to_lineno(_get_caller_frame(), add_filename=True)
@@ -16322,6 +16348,7 @@ class Animate:
16322
16348
  alpha0=None,
16323
16349
  fontsize0=None,
16324
16350
  width0=None,
16351
+ height0=None,
16325
16352
  xy_anchor1=None,
16326
16353
  as_points=None,
16327
16354
  t1=None,
@@ -16342,6 +16369,7 @@ class Animate:
16342
16369
  alpha1=None,
16343
16370
  fontsize1=None,
16344
16371
  width1=None,
16372
+ height1=None,
16345
16373
  flip_horizontal=None,
16346
16374
  flip_vertical=None,
16347
16375
  animation_start=None,
@@ -16494,6 +16522,11 @@ class Animate:
16494
16522
 
16495
16523
  if None, the original width of the image will be used
16496
16524
 
16525
+ height0 : float
16526
+ height of the image to be displayed at time t0 (default see below)
16527
+
16528
+ if None, the original height of the image will be used
16529
+
16497
16530
  t1 : float
16498
16531
  time of end of the animation (default: inf)
16499
16532
 
@@ -16560,6 +16593,8 @@ class Animate:
16560
16593
  width1 : float
16561
16594
  width of the image to be displayed at time t1 (default: width0)
16562
16595
 
16596
+ height1 : float
16597
+ height of the image to be displayed at time t1 (default: height0)
16563
16598
 
16564
16599
  Note
16565
16600
  ----
@@ -16595,6 +16630,8 @@ class Animate:
16595
16630
  self.max_lines0 = max_lines
16596
16631
 
16597
16632
  self.width0 = self.width() if width0 is None else width0
16633
+ self.height0 = self.height() if height0 is None else height0
16634
+
16598
16635
  if image is not None:
16599
16636
  self.image0 = image
16600
16637
 
@@ -16641,6 +16678,7 @@ class Animate:
16641
16678
  self.alpha1 = self.alpha0 if alpha1 is None else alpha1
16642
16679
  self.fontsize1 = self.fontsize0 if fontsize1 is None else fontsize1
16643
16680
  self.width1 = self.width0 if width1 is None else width1
16681
+ self.height1 = self.height0 if height1 is None else height1
16644
16682
  self.xy_anchor1 = self.xy_anchor0 if xy_anchor1 is None else xy_anchor1
16645
16683
 
16646
16684
  self.t1 = inf if t1 is None else t1
@@ -16938,7 +16976,7 @@ class Animate:
16938
16976
 
16939
16977
  def width(self, t=None):
16940
16978
  """
16941
- width position of an animated image object. May be overridden.
16979
+ width of an animated image object. May be overridden.
16942
16980
 
16943
16981
  Parameters
16944
16982
  ----------
@@ -16963,6 +17001,33 @@ class Animate:
16963
17001
 
16964
17002
  return interpolate((self.env._now if t is None else t), self.t0, self.t1, width0, width1)
16965
17003
 
17004
+ def height(self, t=None):
17005
+ """
17006
+ height of an animated image object. May be overridden.
17007
+
17008
+ Parameters
17009
+ ----------
17010
+ t : float
17011
+ current time
17012
+
17013
+ Returns
17014
+ -------
17015
+ height : float
17016
+ default behaviour: linear interpolation between self.height0 and self.height1
17017
+
17018
+ if None, the original height of the image will be used
17019
+ """
17020
+ height0 = self.height0
17021
+ height1 = self.height1
17022
+ if height0 is None and height1 is None:
17023
+ return None
17024
+ if height0 is None:
17025
+ height0 = ImageContainer(self.image0).images[0].size[0]
17026
+ if height1 is None:
17027
+ height1 = ImageContainer(self.image1).images[0].size[0]
17028
+
17029
+ return interpolate((self.env._now if t is None else t), self.t0, self.t1, height0, height1)
17030
+
16966
17031
  def fontsize(self, t=None):
16967
17032
  """
16968
17033
  fontsize of an animate object. May be overridden.
@@ -19656,6 +19721,8 @@ class AnimateImage(Animate2dBase):
19656
19721
  width : float
19657
19722
  width of the image (default: None = no scaling)
19658
19723
 
19724
+ heighth : float
19725
+ height of the image (default: None = no scaling)
19659
19726
 
19660
19727
  text : str, tuple or list
19661
19728
  the text to be displayed
@@ -19791,6 +19858,7 @@ class AnimateImage(Animate2dBase):
19791
19858
  x: Union[float, Callable] = None,
19792
19859
  y: Union[float, Callable] = None,
19793
19860
  width: Union[float, Callable] = None,
19861
+ height: Union[float, Callable] = None,
19794
19862
  text: Union[str, Callable] = None,
19795
19863
  fontsize: Union[float, Callable] = None,
19796
19864
  textcolor: Union[ColorType, Callable] = None,
@@ -19833,6 +19901,7 @@ class AnimateImage(Animate2dBase):
19833
19901
  x=0,
19834
19902
  y=0,
19835
19903
  width=None,
19904
+ height=None,
19836
19905
  text="",
19837
19906
  fontsize=15,
19838
19907
  textcolor="bg",
@@ -19915,10 +19984,10 @@ class ComponentGenerator(Component):
19915
19984
 
19916
19985
  Parameters
19917
19986
  ----------
19918
- component_class : callable, usually a subclass of Component or Pdf or Cdf distribution
19987
+ component_class : callable, usually a subclass of Component or Pdf/Pmf or Cdf distribution
19919
19988
  the type of components to be generated
19920
19989
 
19921
- in case of a distribution, the Pdf or Cdf should return a callable
19990
+ in case of a distribution, the Pdf/Pmf or Cdf should return a callable
19922
19991
 
19923
19992
  generator_name : str
19924
19993
  name of the component generator.
@@ -20478,7 +20547,7 @@ class _Distribution:
20478
20547
  If, after number_of_tries retries, the sampled value is still not within the given bounds,
20479
20548
  fail_value will be returned
20480
20549
 
20481
- Samples that cannot be converted (only possible with Pdf and CumPdf) to float
20550
+ Samples that cannot be converted (only possible with /Pmf and CumPdf/CumPmf) to float
20482
20551
  are assumed to be within the bounds.
20483
20552
  """
20484
20553
  return Bounded(self, lowerbound, upperbound, fail_value, number_of_retries, include_lowerbound, include_upperbound).sample()
@@ -20718,7 +20787,7 @@ class Bounded(_Distribution):
20718
20787
  If, after number_of_tries retries, the sampled value is still not within the given bounds,
20719
20788
  fail_value will be returned
20720
20789
 
20721
- Samples that cannot be converted to float (only possible with Pdf and CumPdf)
20790
+ Samples that cannot be converted to float (only possible with Pdf/Pmf and CumPdf)
20722
20791
  are assumed to be within the bounds.
20723
20792
  """
20724
20793
 
@@ -22214,6 +22283,9 @@ class Pdf(_Distribution):
22214
22283
 
22215
22284
  If it is a salabim distribution, not the distribution,
22216
22285
  but a sample will be returned when calling sample.
22286
+
22287
+
22288
+ This method is also available under the name Pmf
22217
22289
  """
22218
22290
 
22219
22291
  def __init__(self, spec: Union[Iterable, Dict], probabilities=None, time_unit: str = None, randomstream: Any = None, env: "Environment" = None):
@@ -22358,9 +22430,151 @@ class Pdf(_Distribution):
22358
22430
  return self._mean
22359
22431
 
22360
22432
 
22433
+ class Pmf(Pdf):
22434
+ """
22435
+ Probability mass function
22436
+
22437
+ Parameters
22438
+ ----------
22439
+ spec : list, tuple or dict
22440
+ either
22441
+
22442
+ - if no probabilities specified:
22443
+
22444
+ list/tuple with x-values and corresponding probability
22445
+ dict where the keys are re x-values and the values are probabilities
22446
+ (x0, p0, x1, p1, ...xn,pn)
22447
+
22448
+ - if probabilities is specified:
22449
+
22450
+ list with x-values
22451
+
22452
+ probabilities : iterable or float
22453
+ if omitted, spec contains the probabilities
22454
+
22455
+ the iterable (p0, p1, ...pn) contains the probabilities of the corresponding
22456
+ x-values from spec.
22457
+
22458
+ alternatively, if a float is given (e.g. 1), all x-values
22459
+ have equal probability. The value is not important.
22460
+
22461
+ time_unit : str
22462
+ specifies the time unit
22463
+
22464
+ must be one of "years", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds"
22465
+
22466
+ default : no conversion
22467
+
22468
+
22469
+ randomstream : randomstream
22470
+ if omitted, random will be used
22471
+
22472
+ if used as random.Random(12299)
22473
+ it assigns a new stream with the specified seed
22474
+
22475
+ env : Environment
22476
+ environment where the distribution is defined
22477
+
22478
+ if omitted, default_env will be used
22479
+
22480
+ Note
22481
+ ----
22482
+ p0+p1=...+pn>0
22483
+
22484
+ all densities are auto scaled according to the sum of p0 to pn,
22485
+ so no need to have p0 to pn add up to 1 or 100.
22486
+
22487
+ The x-values can be any type.
22488
+
22489
+ If it is a salabim distribution, not the distribution,
22490
+ but a sample will be returned when calling sample.
22491
+
22492
+ This method is also available under the name Pdf
22493
+
22494
+ """
22495
+
22496
+ def __repr__(self):
22497
+ return "Pmf"
22498
+
22499
+ def print_info(self, as_str: bool = False, file: TextIO = None) -> str:
22500
+ """
22501
+ prints information about the distribution
22502
+
22503
+ Parameters
22504
+ ----------
22505
+ as_str: bool
22506
+ if False (default), print the info
22507
+ if True, return a string containing the info
22508
+
22509
+ file: file
22510
+ if None(default), all output is directed to stdout
22511
+
22512
+ otherwise, the output is directed to the file
22513
+
22514
+ Returns
22515
+ -------
22516
+ info (if as_str is True) : str
22517
+ """
22518
+ result = []
22519
+ result.append("Pmf distribution " + hex(id(self)))
22520
+ result.append(" randomstream=" + hex(id(self.randomstream)))
22521
+ return return_or_print(result, as_str, file)
22522
+
22523
+ def sample(self, n: int = None) -> Any:
22524
+ """
22525
+ Parameters
22526
+ ----------
22527
+ n : number of samples : int
22528
+ if not specified, specifies just return one sample, as usual
22529
+
22530
+ if specified, return a list of n sampled values from the distribution without replacement.
22531
+ This requires that all probabilities are equal.
22532
+
22533
+ If n > number of values in the Pmf distribution, n is assumed to be the number of values
22534
+ in the distribution.
22535
+
22536
+ If a sampled value is a distribution, a sample from that distribution will be returned.
22537
+
22538
+ Returns
22539
+ -------
22540
+ Sample of the distribution : any (usually float) or list
22541
+ In case n is specified, returns a list of n values
22542
+
22543
+ """
22544
+ if self.supports_n:
22545
+ if n is None:
22546
+ return self.randomstream.sample(self._x, 1)[0]
22547
+ else:
22548
+ if n < 0:
22549
+ raise ValueError("n < 0")
22550
+ n = min(n, len(self._x))
22551
+ xs = self.randomstream.sample(self._x, n)
22552
+ return [x.sample() if isinstance(x, _Distribution) else x for x in xs]
22553
+ else:
22554
+ if n is None:
22555
+ r = self.randomstream.random()
22556
+ for cum, x in zip([0] + self._cum, [0] + self._x):
22557
+ if r <= cum:
22558
+ if isinstance(x, _Distribution):
22559
+ return x.sample()
22560
+ return x
22561
+ else:
22562
+ raise ValueError("not all probabilities are the same")
22563
+
22564
+ def mean(self) -> float:
22565
+ """
22566
+ Returns
22567
+ -------
22568
+ mean of the distribution : float
22569
+ if the mean can't be calculated (if not all x-values are scalars or distributions),
22570
+ nan will be returned.
22571
+ """
22572
+ return self._mean
22573
+
22574
+
22361
22575
  class CumPdf(_Distribution):
22362
22576
  """
22363
- Cumulative Probability distribution function
22577
+ Cumulative Probability mass function
22364
22578
 
22365
22579
  Parameters
22366
22580
  ----------
@@ -22413,6 +22627,8 @@ class CumPdf(_Distribution):
22413
22627
 
22414
22628
  If it is a salabim distribution, not the distribution,
22415
22629
  but a sample will be returned when calling sample.
22630
+
22631
+ This method is also available under the name CumPmf
22416
22632
  """
22417
22633
 
22418
22634
  def __init__(
@@ -22528,6 +22744,116 @@ class CumPdf(_Distribution):
22528
22744
  return self._mean
22529
22745
 
22530
22746
 
22747
+ class CumPmf(CumPdf):
22748
+ """
22749
+ Cumulative Probability mass function
22750
+
22751
+ Parameters
22752
+ ----------
22753
+ spec : list or tuple
22754
+ either
22755
+
22756
+ - if no cumprobabilities specified:
22757
+
22758
+ list with x-values and corresponding cumulative probability
22759
+ (x0, p0, x1, p1, ...xn,pn)
22760
+
22761
+ - if cumprobabilities is specified:
22762
+
22763
+ list with x-values
22764
+
22765
+ cumprobabilities : list, tuple or float
22766
+ if omitted, spec contains the probabilities
22767
+
22768
+ the list (p0, p1, ...pn) contains the cumulative probabilities of the corresponding
22769
+ x-values from spec.
22770
+
22771
+
22772
+ time_unit : str
22773
+ specifies the time unit
22774
+
22775
+ must be one of "years", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds"
22776
+
22777
+ default : no conversion
22778
+
22779
+
22780
+ randomstream : randomstream
22781
+ if omitted, random will be used
22782
+
22783
+ if used as random.Random(12299)
22784
+ it assigns a new stream with the specified seed
22785
+
22786
+ env : Environment
22787
+ environment where the distribution is defined
22788
+
22789
+ if omitted, default_env will be used
22790
+
22791
+ Note
22792
+ ----
22793
+ p0<=p1<=..pn>0
22794
+
22795
+ all densities are auto scaled according to pn,
22796
+ so no need to have pn be 1 or 100.
22797
+
22798
+ The x-values can be any type.
22799
+
22800
+ If it is a salabim distribution, not the distribution,
22801
+ but a sample will be returned when calling sample.
22802
+
22803
+ This method is also available under the name CumPdf
22804
+ """
22805
+
22806
+ def __repr__(self):
22807
+ return "CumPmf"
22808
+
22809
+ def print_info(self, as_str: bool = False, file: TextIO = None) -> str:
22810
+ """
22811
+ prints information about the distribution
22812
+
22813
+ Parameters
22814
+ ----------
22815
+ as_str: bool
22816
+ if False (default), print the info
22817
+ if True, return a string containing the info
22818
+
22819
+ file: file
22820
+ if None(default), all output is directed to stdout
22821
+
22822
+ otherwise, the output is directed to the file
22823
+
22824
+ Returns
22825
+ -------
22826
+ info (if as_str is True) : str
22827
+ """
22828
+ result = []
22829
+ result.append("CumPmf distribution " + hex(id(self)))
22830
+ result.append(" randomstream=" + hex(id(self.randomstream)))
22831
+ return return_or_print(result, as_str, file)
22832
+
22833
+ def sample(self) -> Any:
22834
+ """
22835
+ Returns
22836
+ -------
22837
+ Sample of the distribution : any (usually float)
22838
+ """
22839
+ r = self.randomstream.random()
22840
+ for cum, x in zip([0] + self._cum, [0] + self._x):
22841
+ if r <= cum:
22842
+ if isinstance(x, _Distribution):
22843
+ return x.sample()
22844
+ return x
22845
+
22846
+ def mean(self) -> float:
22847
+ """
22848
+ Returns
22849
+ -------
22850
+ mean of the distribution : float
22851
+ if the mean can't be calculated (if not all x-values are scalars or distributions),
22852
+ nan will be returned.
22853
+ """
22854
+ return self._mean
22855
+
22856
+
22531
22857
  class External(_Distribution):
22532
22858
  """
22533
22859
  External distribution function
@@ -24127,7 +24453,7 @@ class _APNG:
24127
24453
 
24128
24454
  def to_bytes(self):
24129
24455
  CHUNK_BEFORE_IDAT = {"cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "tRNS", "pHYs", "sPLT", "tIME", "PLTE"}
24130
- PNG_SIGN = b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"
24456
+ PNG_SIGN = b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"
24131
24457
  out = [PNG_SIGN]
24132
24458
  other_chunks = []
24133
24459
  seq = 0
@@ -26601,8 +26927,8 @@ def getfont(fontname, fontsize):
26601
26927
  return getfont.lookup[(fontname, fontsize)]
26602
26928
  else:
26603
26929
  getfont.lookup = {}
26604
- if fontname=="":
26605
- a=1
26930
+ if fontname == "":
26931
+ a = 1
26606
26932
  if isinstance(fontname, str):
26607
26933
  fontlist1 = [fontname]
26608
26934
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: salabim
3
- Version: 24.0.13
3
+ Version: 24.0.14.post3
4
4
  Summary: salabim - discrete event simulation in Python
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://salabim.org
@@ -0,0 +1,10 @@
1
+ salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
2
+ salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,1106
3
+ salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
4
+ salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
5
+ salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
6
+ salabim/salabim.py,sha256=LkXx4KGzg9FaYfe4NUBb2Zm2Iy4v1B2kyHks7cwsWoI,1113664
7
+ salabim-24.0.14.post3.dist-info/METADATA,sha256=4yHEwkcBMUAj2CtFsi3y4s7zkJTzSvLkkm0h3g6vgiI,3456
8
+ salabim-24.0.14.post3.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
9
+ salabim-24.0.14.post3.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
10
+ salabim-24.0.14.post3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,10 +0,0 @@
1
- salabim/DejaVuSansMono.ttf,sha256=Z_oIXp5yp1Zaw2y2p3vaxwHhjHpG0MFbmwhxSh4aIEI,335068
2
- salabim/LICENSE.txt,sha256=qHlBa-POyexatCxDTjSKMlYtkBFQDn9lu-YV_1L6V0U,1106
3
- salabim/__init__.py,sha256=r7qPLvlmX0dkZDyjuTo8Jo3ex3sD1L4pmK6K5ib9vyw,56
4
- salabim/calibri.ttf,sha256=RWpf8Uo31RfvGGNaSt9-2sXSuN87AVE_NFMRsV3LhBk,1330156
5
- salabim/mplus-1m-regular.ttf,sha256=EuFHr90BJjuAn_r5MleJFN-WfkeWJ4tf7DweI5zr8tU,289812
6
- salabim/salabim.py,sha256=NzhLkqRi8niqF9eQQPZRxJueQBROP0084q6qHrY6Qzc,1103953
7
- salabim-24.0.13.dist-info/METADATA,sha256=-xWemNdEOZ-EbstXw49IqGKhr97mg85QxyuDLa2LtGA,3450
8
- salabim-24.0.13.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
9
- salabim-24.0.13.dist-info/top_level.txt,sha256=UE6zVlbi3F6T5ma1a_5TrojMaF21GYKDt9svvm0U4cQ,8
10
- salabim-24.0.13.dist-info/RECORD,,