Salabim

Latest version: v25.0.8

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

Scan your dependencies

Page 9 of 28

22.0.8

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

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

Salabim has a new feature: trajectories.
These can be used as:

- a trajectory an animated object should follow in time,
including getting the required duration
- placing components of a queue along a trajectory

A trajectory can consist of a number of subtrajectories,
where each can be a polygon (optionally splined) or a circle (segment)

The position on the trajectory in relation to the time is
optionally described a uniform acceleration/deceleration
with a given initial speed, final speed as well a maximum speed.

The various classes and their methods are in the reference section
of the documentation.
A manual update covering this subject is in the works.

See also sample models "Demo trajectory.py".

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

AnimateQueue and Queue.animate can now place the animation objects on a given
trajectory, by specifying
direction="t", trajectory=...
The trajectory x, y and angle method are called with the cumulated 'length' of the
animation objects dimx parameter (dimy is ignored).

See also sample models "Demo trajectory animate queue.py"

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

AnimateImage now supports .heic (Apple's propriety High Efficiency Image File Format) files.
In order to read these files, pillow-heif has to be installed, e.g. with
pip install pillow-heif
This functionality is not available under Pythonista.

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

The AnimateSlider parameters are changed considerably as the previous version
was not consistent and missed useful functionality.

New parameters are:
foreground_color : colorspec
color of the foreground (default "fg")

background_color : colorspec
color of the backgroundground (default "bg")

trough_color : colorspec
color of the trough (default "lightgrey")

show_value : boolean
if True (default), show values; if False don't show values (thus only showing the label)

The following parameters were available, but actually not used at all:
linecolor
labelcolor
layer
They will remain accepted for compatibility reasons.

Added the method AnimateSlider.label:
Parameters
----------
text : str
new label
if omitted, no change

Returns
-------
Current label : str

With the new label method, it's easy to make dynamic labels, like:

import salabim as sim
import datetime

def action(v):
v_as_datetime = datetime.datetime(2022, 1, 1) + datetime.timedelta(days=int(v))
an0.label(f"{v_as_datetime:%Y-%m-%d}")

env = sim.Environment()
an0 = sim.AnimateSlider(x=100, y=100, action=action, width=500, height=30, v=30, vmin=0, vmax=365, resolution=1, fontsize=12, show_value=False)
env.animate(True)
env.run(sim.inf)

See also sample model "Demo slider.py"

Note that the Pythonista implementation does not use all given parameters.

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

In order to let AnimateCombined dynamic attributes work the same way as ordinary
Animatexxx objects, getting an attribute for an AnimateCombined object now returns
that attribute of the first animation object that has such an attribute, rather
than the 'shared' value.
If an attribute can't be found at all, now an AttributeError is raised, rather than
a ValueError.

As the animation_objects in AnimateCombined are now a list, rather than a set,
AnimateCombined.add is replaced by AnimateCombined.append.


Bugfix (0)
----------

Fixed a bug in resource requesting (thanks to Cameron Powell)

Bugfix (1)
----------

Bug in Monitor.xt() re adding now (introduced in version 22.0.6) fixed.

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

A minor mistake in the docstring of animation_paramters re show_menu_buttons corrected

22.0.7

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

New functionality
-----------------

The method Environment.background3d_color can be used to set or query the
background color of a 3D window. Note that this can be changed at any time
and will be immediately in effect.
Related to this is a new parameter background3d_color of Envuironment.animation_parameters,
which has the same functionality.

Renamed methods (0)
-------------------

For consistency reasons, the following methods are renamed

22.0.6

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

Bugfix (0)
----------

In the just released version 22.0.5, a serious bug made that animations did
not run correctly.
Fixed.

Bugfix (1)
----------

In AnimateMonitor / Monitor.animate(), the fillcolor rectangle was not correctly
positioned behind the label lines, which were in turn not positioned behind
the plot line/points.
Fixed.

22.0.5

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

Improved functionality (0)
--------------------------

Now a call to sim.reset() will destroy a previous tkinter canvas window (if any).
That makes it much easier to use salabim in an interactive environment like iPython or Jupyter.

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

The new function searchsorted offers (nearly) the same functionality as
numpy.searchsorted.
If numpy is installed the function delegates to numpy.searchsorted.

Added functionality (1)
-----------------------

The new function arange offers (nearly) the same functionality as
numpy.arange.
If numpy is installed the function delegates to numpy.arange.

Added functionality (3)
-----------------------

The new function linspace offers similar functionality as numpy.linspace.
The function returns a list, rather than an array, which
is usually more practical in a salabim model.

Added functionality (4)
-----------------------

The function interp now also supports lists and tuples.
This can be useful to interpolate lines and polygons directly.
The function now uses internally a binary search (bisect).
Furthermore, the function does not delegate to numpy anymore as this is just slower.

Added functionality (5)
-----------------------

The new method Environment.color_interp() can be used to
interpolate colors, interp() style. E.g.
sim.color_interp(t, (0, 10, 20), ('red', 'blue', 'green'))
This allows for more than two times/colors to be specified as opposed to Environment.colorinterpolate
which supports only two times/colors (with a different API).

Added functionality (6)
-----------------------

The new method Monitor.start_time() will return the creation time or the last time of a reset
of this monitor.

Added functionality (7)
-----------------------

AnimateMonitor() and Monitor.animate() now have a parameter as_points, which allows the user
to override the default for tallied points, which is False for level monitors and
True for non level monitors.

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

It is now possible to get the actual animation time with
Environment.t()
Note that in a simulation step, env.t() is always equal to env.now(), even if animation is off.

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

When animating and requesting any of the level monitor statistics, these ended at env.now(),
but in practice, it is better to end these with env.t.
Changed behaviour, so it is now possible to have a dynamic mean, std, percentile, etc.
up to the current animation time.

Internal changes / change in functionality (0)
----------------------------------------------

In version 20.0.3 the internals of the parent parameter in all Animatexxx was changed.
Unfortunately, this change is not guaranteed to work.
Therefore, from this version on, the animation object(s) of which a component is parent
will be removed at the very moment that component becomes a data component (i.e.
terminates).
The new method Component.remove_animation_children() can be used also to remove all the
animation objects of which the component is parent.

Perfomance improvement (0)
--------------------------

When calling make_pil_image with self.type == "text" and no text to display,
the attributes x, y, angle, ... were evaluated always.
Now, the method returns immediately by placing the check code at the top
of the method.

Bugfix (0)
----------

When Environment.reset_now() was called, animations could be wrong, because the time communicated
to dynamic attributes was not set correctly.
Fixed.

Bugfix (1)
----------

A bug in Monitor.reset() made that the start attribute of a monitor was not set properly when
a reset_now() had been issued. Fixed.

Documentation of 3D camera control keys
---------------------------------------

<Left> rotate camera -1 degree
<Right> rotate camera +1 degree


<Up> zoom in 0.9 *
<Down> zoom out 1.1 *

<z> lower the camera 0.9 *
<Z> raise the camera 1.1 *

<Shift-Up> move camera in z-plane 0.9 *
<Shift-Down> move camera in z-plane 1.1 *

<Alt-Left> move camera x - 10
<Alt-Right> move camera x + 10
<Alt-Down> move camera y - 10
<Alt><Up> move camera y + 10

<Control-Left> center x - 10
<Control-Right> center x + 10
<Control-Down> center y - 10
<Control-Down> center y + 10

<o> field of view * 0.9
<O> field of view * 1.1

<t> tilt camera +1 degree
<T> tilt camera -1 degree

<r> rotate camera axis +1 degree
<R> rotate camera axis -1 degree

<p> print current camera control settings

22.0.4

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

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

When an animation window was closed with the X button in the upper right-hand corner.
the application used to crash.
From this version on, the simulation will turn off the animation and raise a
SimulationStopped exception.

Animation functionality (0)
---------------------------

All animation primitives *) now have a show() method that can be used
to show an animation objects that had been removed.
It is possible to use show for animation objects that are already shown.

All animation primitives *) now have a remove() method that can be used
take an animation object off the animation objects set.
This is different from setting visible to False, as it is not checked
anymore.
It is possible to use remove for animation objects that are already removed.

All animation primitives *) now have a isremoved() method, that returns
True if the animation object is on the animation objects set. False,
otherwise.

All animation primitives *) now have a (dynamic) keep parameter method that can be used
to remove an animation object once the values becomes False.
Note that even if you set keep=True, later, the animation object will not be
reshown as the animation object is not checked anymore.
If you want an animation object which was removed by keep=False, use the
show() method (at the same time making sure that keep=True).

*) AnimateCircle, AnimateImage, AnimateLine, AnimatePolygon, AnimatePoints, AnimateRectangle, AnimateText,
Animate3dBar, Animate3dBase, Animate3dBox, Animate3dGrid, Animate3dLine, Animate3dObj,
Animate3dRectangle, Animate3dSphere,
AnimateQueue, Animate3dQueue and AnimateMonitor

Animation functionality (1)
---------------------------

AnimateCombined now acts like a set instead of a list.

Animation internals (0)
-----------------------

The animation engine is internally changed rather dramatically.
Previously AnimateLine, AnimateRectangle, etc. delegated to Animate.
Now Animate delegates to AnimateLine, AnimateRectangle, ...
Animate itself is not used internally anymore.
This change made it possible to use the more versatile dynamic attribute method and is
potentially safer.
This change should have no impact on existing models. But, you never know ...

Bugfix (0)
----------

A bug introduced in version 22.0.3 made it impossible to use vertical_map properly in AnimateMonitor.
Fixed.

Bugfix (1)
----------

A bug in over3d animation fixed.

Bugfix (2)
----------

In version 22.0.3 the add_attr method in animation primitives *) was removed by mistake. Fixed.

22.0.3

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

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

AnimateMonitor is completely rebuilt to allow dynamic attributes.
From now on, *ALL* attributes can be specified as a constant, a function of t or a method witn t as
argument.
This is particularly useful for dynamic ranges, both horizontally and vertically.

Now AnimateMonitor also supports visible and over3d (both dynamic) and screen_coordinates.

it is possible to get the monitor associated with AnimateMonitor via the monitor() method.
This can be handy in writing dynamic lambda function, e.g. to get the maximum of a monitor.
(see example below)

Exam


ple:

import salabim as sim


class X(sim.Component):
def process(self):
v0 = v1 = 10
while True:
v0 = max(0, min(500, v0 + sim.Uniform(-1, 1)() * 10))
level_monitor.tally(v0)
v1 = max(0, min(500, v1 + sim.Uniform(-1, 1)() * 10))
non_level_monitor.tally(v1)
yield self.hold(1)


env = sim.Environment()
env.speed(10)

sim.AnimateText("Demonstration dynamic AnimateMonitor", fontsize=20, y=700, x=100)

level_monitor = sim.Monitor("level_monitor", level=True)
non_level_monitor = sim.Monitor("non_level_monitor")
X()
sim.AnimateMonitor(
level_monitor,
linewidth=3,
x=100,
y=100,
width=900,
height=250,
vertical_scale=lambda arg, t: min(50, 250 / arg.monitor().maximum()),
labels=lambda arg, t: [i for i in range(0, int(arg.monitor().maximum()), 10)],
horizontal_scale=lambda t: min(10, 900 / t),
)
sim.AnimateMonitor(
non_level_monitor,
linewidth=5,
x=100,
y=400,
width=900,
height=250,
vertical_scale=lambda arg, t: min(50, 250 / arg.monitor().maximum()),
labels=lambda arg, t: [i for i in range(0, int(arg.monitor().maximum()), 10)],
horizontal_scale=lambda t: min((10, 900 / t)),
)

env.animate(True)
env.run(120)

Enjoy this new feature!

Changed functionality (0)
-------------------------
The behaviour of setting/getting attributes in AnimateCombined is changed.

If you query an attribute of a combined animation object, it will now return the
value of the attribute, only if all combining animation objects (that have this attribute)
are the equal.
If they are not equal or no attribute is found at all, a ValueError will be raised.

If you set an attribute, it will set that attribute only for combining animation
objects that have indeed that attribute present. It is not an error if no
attribute is found at all.

Examples:
an0 = sim.AnimateRectangle(spec=(-10,-10,10,10))
an1 = sim.AnimateCircle(radius=5, fillcolor="white")
an2 = sim.AnimateCircle(radius=10, fillcolor="red")

an = sim.AnimateCombined([an0, an1, an2])

an.x = 5 will set x=0 for an0, an1 and an2
an.radius = 7 will set radius=7 for an1 and an2, but not an0

print(an.x) will print 5 as x==5 for an0, an1 and an2
print(an.radius)
will print 7 as radius==7 for an1 and an2 (an0 does not have a radius and is ignored)

print(an.fillcolor)
will raise a ValueError because an0, an1 and an2 do not have the same fillcolor

print(an.image)
will raise a ValueError because neither an0, an1 nor an2 have an image attribute

Changed functionality (1)
-------------------------
sim.Resource now has an initial_claimed_quantity parameter, that can be used only
for anonymous resources. If not zero, the resource starts with a quantity in it.

Example:
r = sim.Resource("r", capacity=100, initial_claimed_quantity=50, anonymous=True)

Changed functionality (2)
-------------------------
The over3d parameter of
sim.AnimateText, sim.AnimateLine, sim.AnimatePoints, sim.AnimatePolygon,
sim.AnimateImage, sim.AnimateRectangle
is now dynamic.

Bugfix (0)
-----------
There was a bug in AnimateLine, AnimateRectangle and AnimatePolygon that prevented from using as_points properly.
Fixed.

Page 9 of 28

© 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.