Salabim

Latest version: v24.0.9

Safety actively analyzes 642283 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 5 of 25

23.1.4

==========================

New functionality (0)
---------------------

Introduced sim.full_screen() / env.full_screen() , which
creates a true full screen window, without a title, where
x0=0, y0=0, x1=width of screen
(Inspired by a remark from Lukas Hollenstein)

New parameter (0)
-----------------

The method sim.width() / env.width() now have a second parameter
adjust_x0_x1_y0, which is False by default.
If adjust_x0_x1_y0 is True, apart from setting the width,
x0 will be set to 0, y0 will be set to 0 and x1 will be set to the given width.
E.g.
env.width(1000, True)

Note that existing programs won't be affected, as the parameter
adjust_x0_x1_y0 is False by default.

New functionality (1)
---------------------

sim.AnimateImage / env.AnimateImage now supports animated GIFs and
animated .webp files.

Therefore, AnimateImage has six new parameters:

- animation_start (simulation) time that the animation should start
- animation_repeat if False (default) no repeat, if True, repeat
- animation_pingpong if False (default) no pingpong, if True, first goes forward then backward
- animation_speed specifies how fast the animation should be (relative to env.speed)
- animation_from specifies the time in the video from which to animate
- animation_to specifies the time in the video to which to animate

Note that these parameters may be specified for non animated images as well,
but will have no meaning, then.
All these parameters are dynamic.

The AnimateImage now has a method duration that returns the duration of the image
(0 if not animated).

Note that animated GIFs and .webp files can have a transparent background,
which makes it ideal for showing moving objects, like vehicles, cranes, animals, etc.

New functionality (2)
---------------------

It is now possible to produce .webp format videos.
E.g.
with env.video("my_video.webp"):
env.run(10)

New functionality (3)
---------------------

The class sim.AnimateImage / env.AnimateImage can now be used with
.webp files (still or animated).
E.g.
env.AnimateImage(image="my_picture.webp")

New functionality (4)
---------------------

The class sim.AnimateImage / env.AnimateImage can now be used also to
animate an image given by a URL.
Any image parameter that contains // will be opened as a URL.
E.g.
env.AnimateImage("https://salabim.org/manual/_images/2d1.gif")

New functionality (5)
---------------------

The class sim.AnimateImage / env.AnimateImage now have two new (dynamic)
boolean parameters:

- flip_horizontal
- flip_vertical
Both parameters are False by default.
When True, the image is flipped either horizontal or vertical.
Note that this functionality is also available for animated
images.
E.g.
env.AnimateImage("mypicture.webp", flip_vertical=lambda t: t > 10)

New functionality (6)
---------------------

The new function sim.video_duration() / method env.video_duration()
will return the length or a given animated GIF/Webp file or URL.
This can be useful in animating a GIF/Webp file or URL.
E.g.
duration = env.video_duration("my_video.gif")


New functionality (7)
---------------------

ComponentGenerator has a new parameter: at_end. If not specified, no action when the component generator ends.
If a parameterless function is specified, this function will be called when the component generator ends.
The most obvious usage of this is to reactivate main when all components are generated.

ComponentGenerator(number=10, iat=env.Uniform(1,2), at_end=lambda: env.main().activate())

Performance improvement (0)
---------------------------

When using AnimateImage, all images are now properly cached, which improves
performance under certain conditions.

Support for Pythonista 3.4 (0)
------------------------------

Fixed a problem in the set_aliases routine.

A bug in Pythonista 3.4 makes that the using the Calibri font with fontsize between 12 and 17 crashes the
system. Therefore, on Pythonista, Calibri font is replaced by the Arial font, until the Pythonista bug
is fixed.

Bug fix (0)
-----------

AnimateCombined did not handle a non list animation_objects parameter correctly. Fixed.
(bug reported by Michiel Luyken)

Bug fix (1)
-----------

Animated GIFs could not handle a transparent background color properly. Fixed.

Bug fix (2)
-----------

Under Python 3.10 (Pythonista only?) classes that have no __init__ method, don't seem to have a signature,
which lead to some problems in the aliasing of globals into Environment. Fixed.

Bug fix (3)
-----------

When using applying a filter for Store.from_store() the wrong component was returned. Fixed.
(bug reported by Martin Kunkel, fix slightly different)

Bug fix (4)
-----------

A bug in _AnimateIntro and _AnimateExtro made that Environment(isdefault_env=False) didn't work properly.
Fixed.
(bug reported by Michiel Luyken)

Bug fix (5)
-----------

Under Pythonista, the simulation time was not animated correctly in unsynced mode. Fixed.

HTML documentation readability enhancement (0)
----------------------------------------------

In the sidebar of the HTML documentation, level 4 items are now shown in a larger font,
which makes it easier to read.
(Inspired by a remark from Michiel Luyken)

23.1.3

==========================

New functionality (0)
---------------------

Introduced two new functions to get the width and height of the screen:
sim.screen_width() / env.screen_width()
sim.screen_height() / env.screen_height()
So now it is easy to have a full-screen animation:
env.width(env.screen_width())
env.height(env.screen_height())
env.x1(env.width())
(Inspired by a question by Michiel Luyken)

Improved type hinting (0)
-------------------------

The type hints and docstrings in sim.Environment cover now all
classes and methods.

Improved type hinting (1)
-------------------------

Component.from_store now also has a type hint ("Component"), so
c = self.from_store(store)
will show the typing info.
(inspired by a discussion with Lukas Hollenstein)

Docstrings improvement (0)
--------------------------

Docstrings used to contain many |n| characters, which were there
to render the reference section of the documentation.
But, these characters were annoying and did not work out well in
tooltips.
From now on, the docstrings don't contain |n| characters anymore,
and can still be used in the automatic documentation-building process.
(inspired by a discussion with Lukas Hollenstein)

Bug fix (0)
-----------

A minor error in tracing from_store honor / to_store honor fixed.

Bug fix (1)
-----------

Error when honouring a to_store request for multiple stores fixed.

23.1.2

==========================

Added functionality(0)
----------------------

When animating a queue, with a trajectory, it is now possible to specify the
x and y coordinates, which may even be dynamic.
And the trajectory may be dynamic now as well.

It is now documented that for usage in Queue.animate() or AnimateQueue,
t0 should be set to 0 for at least the first segment of a trajectory.

Changed functionality (0)
-------------------------

It is more logical to use urgent=True in calls to Component.from_store and
Component.to_store. Therefore the default value for urgent in these methods
is now True.

Improved type hint handling (0)
-------------------------------

The recently introduced functionality to use env. prefix where sim. prefix
was required (like env.Component instead of sim.Component) did not show the
type hints in IDEs.
From this version type hints and the docstring will show these correctly.

The consequence of this change is an increase in the size of the source code,
but that shouldn't cause any problems.

Alternative way to initialize a simulation (0)
----------------------------------------------

It is quite common to start an app(lication) with ::

app = App()

This is now also possible with salabim as sim.App is now just an alias of
sim.Environment. So ::

app = sim.App(trace=True)
app.ComponentGenerator(X, iat=app.Exponential(10))
app.run(app.Uniform(10,20))

is now valid code.

Note that the env parameter in several class definitions has not been changed, though.
This might not cause too many problems as env= is hardly ever used in practice
(as far as I know).

Bug fix (0)
-----------

If Trajectory.length() was called without a time (t), an exception was raised. Fixed.

Bug fix (1)
-----------

When using sim.ComponentGenerator the default environment was not propagated correctly. Fixed.

Documentation updates (0)
-------------------------

The documentation now makes clear that t0 should be 0 in case a trajectory is
to be used as a trajectory for queue animation.

Documentation updates (1)
-------------------------

The HTML documentation now uses the better legible rtd (Read The Docs) theme.
Also, many additions and changes have been done.

23.1.1

==========================

New functionality (0)
---------------------

The t- and x-values of a monitor (level or non level) can now be saved as
a pandas dataframe, which can be useful for further data analysis.

All you have to do is:
df = mon.as_dataframe()

When dealing with level monitors, this might not be very useful as
most analyses assume a uniform (equidistant) t-scale.
Therefore, salabim also offers the possibility to resample the
monitor into a dataframe, like
df = mon.as_resampled_dataframe(delta_t=1)
Like this, the monitor will be resampled with a frequency of 1 time unit.
The lower delta_t, the more accurately the dataframe follows the real values,
albeit at the cost of a larger dataframe.

It is possible to resample multiple monitors into one pandas dataframe.

See the documentation (Monitor and Reference chapter) for details.

Changed functionality (0)
-------------------------

Considerable change in the implementation and API of stores.

From now a store doesn't *have* a contents queue: It *is* a queue!
This has a lot of advantages. For instance, all normal queue operations
are now also available for stores.

And you can now enter components or take them out, possibly honouring
any pending from_store or to_store.

Note that if the capacity of the store is not inf, the store becomes a
limited capacity queue. That implies that when a component tries to enter
the queue when it is already at its capacity, a ``sim.QueueFullError`` will be raised.

Changing the filter function will now automatically rescan for from_store
honors.
Changing the capacity of a store (with set_capacity will now automatically
rescan for to_store honors), if required.

It is still possible to rescan a store with Store.rescan().

The manual has been updated to reflect the changes.

Changed functionality (1)
-------------------------

The Component.from_store method now supports a very handy way to get the
item (component).
Instead of
yield self.from_store(store)
item = self.from_store_item()
you can now say
item = yield self.from_store(store)

Note that you have to do an assignment! So, something like
yield self.from_store(store).activate()
or
print(yield self.from_store(store).name())
is not possible (it is actually a syntax error)

Even with the item = yield self.from_store(store) syntax, you can
query the item with self.from_store_item()

And it is still allowed to use just
yield self.from_store(store)

The manual has been updated accordingly.

New functionality (0)
---------------------

ComponentGenerator has a new parameter: equidistant.
If equidistant is True, the components will not be randomly distributed over the
given duration, but evenly spread. For instance:
env.ComponentGenerator(X, at=100, till=200, number=3, equidistant=True)
, will generate instances of X at t=100, t=150 and t=200.

If equidistant is True, iat may not be specified.

Optimization (0)
----------------

The method Component.enter_sorted and Queue.add_sorted now search backwards instead of forward,
which is more efficient in case all components have the same priority, which is not uncommon.

Note (0)
--------

Version 23.1.0 introduced the possibility to use env. instead of sim. in almost all cases.
As mentioned you can't use this construction when defining an inherited class, like
class Car(env.Component)
This is simply not accepted.

But there is one case, which is not detected and does not work as expected:

class Car(sim.Component)
def __init__(self, *args, **kwargs):
...
env.Component.__init__(self,*args, **kwargs) instead of sim.Component.__init__(self, *args, **kwargs)

The recommended way is:

class Car(sim.Component)
def __init__(self, *args, **kwargs):
...
super().__init__(*args, **kwargs) instead of sim.Component.__init__(self, *args, **kwargs)

23.1.0

==========================

New functionality (0)
---------------------

This version contains a completely new concept that can make modelling
simpler, particularly for job shops, flow, etc.: stores

A store is essentially a queue (sometimes with limited capacity) that can
hold components.

And we can then request components from the store. If there's a component
in the store, it is returned. But if it is not the requesting component
goes into the requesting state, until something is available in the store.

The same holds for processes putting components in the store: if it
is full, the component that wants to add something to the store goes into
the requesting state. Here we have an unlimited waiting room, though.

Here's the well-known 3 clerk bank sample model with a store:

Bank, 3 clerks (store).py
import salabim as sim


class CustomerGenerator(sim.Component):
def process(self):
while True:
yield self.to_store(waiting_room, Customer())
yield self.hold(sim.Uniform(5, 15).sample())


class Clerk(sim.Component):
def process(self):
while True:
yield self.from_store(waiting_room)
customer = self.from_store_item()
yield self.hold(30)


class Customer(sim.Component):
...


env = sim.Environment(trace=False)
CustomerGenerator()
for _ in range(3):
Clerk()
waiting_room = sim.Store("waiting_room")


env.run(till=50000)

waiting_room.contents().print_statistics()
waiting_room.contents().print_info()

It is possible to specify several stores to get an item from. And likewise,
several stores to put an item.
It is also possible to filter components so to make the requester only get
a certain type of item.

The manual contains a new section on stores, with several examples. See also the
chapter on Modelling.

New functionality (1)
---------------------

From now on every class or function that used to be prefixed with sim.
can also be prefixed with env.

So, for instance:
q = env.Queue("q")
or
store = env.Store("store")
or
env.run(env.inf)

The only place where that is not allowed is for subclassing,
particularly sim.Component. So you still need to say
class Car(sim.Component):
...

Note that explicit setting of env is still possible:
env.Queue("q", env=env0)
is equivalent to
sim.Queue("q", env=env0)

Implicit setting of env is handled like
env0.Queue("q")
is equivalent to
sim.Queue("q", env=env0)

Support functions, like arange can now also be prefixed with env.
So env.arange(0, 10, 0.5) and sim.arange(0, 10, 0.5) are equivalent.

Also prefixable with env are env.inf and env.nan and the exceptions.

New functionality (2)
---------------------

Introduced a context manager Environment.suppress_trace that can
be used to temporarily disable trace. After the context manager block,
the trace status returns to the value before. Usage:
with env.suppress_trace():
car = sim.Component()
This will never print the trace output for component creation.

Changed functionality (0)
-------------------------

In TrajectoryPolygon, the spline may now also be "" (the null string),
denoting no splining.

Added functionality (0)
-----------------------

In the various print_histogram() print_histograms() a new parameter is
introduced: graph_scale, which represents the number of characters to
show 100% in the graphical representation of % and cum%.
This is particularly useful for (this) documentation.

So, ``m.print_histogram()`` might print:

...
<= duration % cum%
0 22.216 22.2 22.2 *****************|
1 32.485 32.5 54.7 ************************* |
2 26.441 26.4 81.1 ********************* |
3 18.858 18.9 100 *************** |
inf 0 0 100 |

, whereas ``m.print_histogram(graph_scale=30)`` will result in:

...
<= duration % cum%
0 22.216 22.2 22.2 ******|
1 32.485 32.5 54.7 ********* |
2 26.441 26.4 81.1 ******* |
3 18.858 18.9 100 ***** |
inf 0 0 100 |


Bug fix (0)
-----------

Trajectories did not always work correctly. Fixed.

Bug fix (1)
-----------

If a queue is animated the title should be the name of the queue by default.
In a recent update, the default was set to the null string, though.
Fixed.

Bug fix (2)
-----------

When saving an animated gif, the duration of the video was not always correct.
Particularly at 30 fps (the default), the duration was actually 90% shorter,
because frame durations are always a multiple of 10 ms.
That means that a 30 fps animated gif will be now actually recorded at 33.33 fps
and have the proper duration.
Fixed.

Documentation (0)
-----------------

The changelog is now part of both the online and pdf documentation.
The pdf version is now kept up-to-date (synced with the online docs).

23.0.1

==========================

Annotation (0)
--------------

Salabim has now type hints on all API classes, methods and functions.
This might help users when using IDEs and other tooling.

Warning (0)
-----------

As this change involved quite a lot of modifications (and some bug fixes),
it is possible that errors were introduced.
Please report any bugs as soon as possible.

Changed functionality / bug fix (0)
-----------------------------------

Due to an error in the sampling of a Poisson distribution, large means
(around 750 and up), always returned 2.
Now, if this happens, salabim falls back to another algorithm,
that works for any mean. But, this is slower than the 'base'
algorithm.

Salabim now offers the possibility to use the numpy Poisson sampling
functionality, which is indeed much faster. For reproducibility
reasons, this feature is disabled by default.
In order to enable numpy Poisson distribution sampling, specify
prefer_numpy = True when defining the Poisson distribution, like
d = sim.Poisson(mean=1000, prefer_numpy=True)
If numpy is not installed, salabim uses the 'normal' algorithm.

Bug fix (0)
-----------

AnimateSlider could not be removed properly. Fixed.

Bug fix (1)
-----------

A bug in AnimateSlider sometimes caused an error in getting the current value (v). Fixed.

Bug fix (2)
-----------

The way caching xweight was built, sometimes resulted in -although statistically correct-
unexpected results for monitor. The fix applied is also more performant.

Page 5 of 25

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.