Salabim

Latest version: v24.0.13

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

Scan your dependencies

Page 4 of 26

23.3.8

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

Enhanced UI functionality (0)
-----------------------------

The UI window layout has been changed to be more useful with
narrower windows.
Some more updates to the appearance.

When the UI is started, the time in the animation window is no longer disabled.
The user can always switch that off with Environment.show_time(False).

Environment.start_ui() now has useful defaults for window_size and window_position.

Environment.start_ui() now has a parameter default_actions, which is True by default.
If False, there are no actions like, pause/go, speed, etc. defined, so the user has to
specify the required actions with the actions parameter.
This is useful to use a different layout or leave out certain elements. Be sure to
use the same keys to be able to use the programmed interactions. However, you
can leave out elements.

It is recommended to use the standard actions as a template:

[sg.Text("", key="-TIME-", metadata=[1, 2], size=200)],
[sg.Button("Pause", key="-PAUSE-GO-", metadata=[1, 2]), sg.Button("Stop", key="-STOP-", button_color=("white", "firebrick3"), metadata=[1, 2])],
[sg.Checkbox("Pause at each step", False, key="-PAUSE-AT-EACH-STEP-", enable_events=True, metadata=[1, 2])],
[sg.Text(f"Pause at{env.get_time_unit(template='(t)')}", key="-PAUSE-AT-TEXT-", size=17), sg.Input("", key="-PAUSE-AT-", size=(10, 20))],
[sg.Text(f"Pause each{env.get_time_unit(template='(d)')}", key="-PAUSE-EACH-TEXT-", size=17), sg.Input("", key="-PAUSE-EACH-", size=(10, 20))],
[
sg.Text("Speed", key="-SPEED-TEXT-", metadata=[1]),
sg.Button("/2", key="-SPEED/2-", metadata=[1]),
sg.Button("*2", key="-SPEED*2-", metadata=[1]),
sg.Input("", key="-SPEED-", size=(7, 10)),
],
[sg.Checkbox("Trace", env.trace(), key="-TRACE-", metadata=[1, 2], enable_events=True)],
[sg.Checkbox("Synced", env.synced(), key="-SYNCED-", metadata=[1], enable_events=True)],
[sg.Checkbox("Animate", True, key="-ANIMATE-", metadata=[1, 2], enable_events=True)],


The simulation did not stop exactly at the time given in 'Pause at'. Fixed.

Added demos (0)
---------------

The program demo_ui.py shows a pretty standard UI with some extra elements.

The program demo_horizontal_ui.py demonstrates the same functionality, but now
with a horizontal UI window. Note that this requires quite a bit more
code than the standard one.
But it demonstrates what is possible.

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

Component.to_store_store did not always return the right store. Fixed.
Thanks to Florian Förster for reporting this bug and the fix.

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

Store.to_store_requesters() returned the wrong queue. Fixed.

23.3.7

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

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

Environment.paused(True) did not call set_start_animation(), which is required. Fixed.

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

Removing and showing an animated monitor did not restore the labels and label lines. Fixed.

23.3.6

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

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

The parameter datetime0 in Environment(), may now be also a string, which is relatively
free format as it uses dateutil.parser.parse.
Note that (unless Environment.dateutil_parse is overridden), it is advised to use
Y-M-D format, e.g.
env = sim.Environment(datetime0="2023-08-17")
Note that for this functionality, dateutil has to be installed, most likely with
pip install python-dateutil

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

The parameter datetime0 in Environment.datetime0(), may now be also a string, which is relatively
free format as it uses dateutil.parser.parse.
Note that (unless Environment.dateutil_parse is overridden), it is advised to use
Y-M-D format, e.g.
env.datetime0("2023-08-17")
Note that for this functionality, dateutil has to be installed, most likely with
pip install python-dateutil


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

The above functionality uses a method Environment.dateutil_parse, which more or less defaults to
def dateutil_parse(self, spec):
import dateutil.parser
return dateutil.parser.parse(spec, dayfirst=False, yearfirst=True)

If other values for dayfirst or yearfirst are desired, formulate a custom method, like
sim.Environment.dateutil_parse = lambda self, spec: dateutil.parser.parse(spec, dayfirst=True, yearfirst=False)

Refer to the Python dateutil.parse documentation for details.

Note that for this functionality, dateutil has to be installed, most likely with
pip install python-dateutil

Changed functionality (3)
-------------------------

If datetime0 is not False, all process interaction methods that require a time, like Component.hold,
Component creation, fail_at parameters, can now be a datetime.datetime, e.g.
comp.hold(till=datetime.datetime(year=2023, month=8, day=17))
Or it can be string containing a relatively free format date, like
comp.hold(till="2023-08_07")
And now it is even possible to use a string:
comp.hold(till="1000")

If datetime0 is not False, all process interaction methods that require a duration, like Component.hold,
Component creation, fail_delay parameters, can now be a datetime.timedelta, e.g.
comp.hold(datetime.timedelta(hours=1)
Vehicle(delay=datetime.timedelta(days=2))
Or it can be string containing a relatively free format duration, like
comp.hold("12:00:00"))
And now it is even possible to use a string:
comp.hold("1000")

Of course, these parameters can also be a callable, like
comp.hold(env.Pdf(("12:00", "13:45", "20:30"), 1))

Note that this functionality is a by-product of the implementation of the not yet documented, but already
available, UI (using PySimpleGUI) functionality.

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

The value of State.value can now be assigned and queried directly. E.g.
my_state.value.value = 3
print(my_state.value.value)
is equivalent to
my_state.set(3)
print(my_state.get())
This can be useful to increment or decrement a state. E.g.
my_state.value.value += 5
is equivalent to
my.state.set(my_state.get() + 5)

The value of Component.mode can now be assigned also like:
my_component.mode.value = "working"
, instead of
my_component.set_mode("working")
This can also be useful to increment or decrement a mode. E.g.
my_component.mode.value += 5
is equivalent to
my_component.set_mode(my_component.mode() + 5)

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

The class Environmnent does not contain a subclass Environment anymore,
so you can't say
env1 = env.Environment()
anymore. This was never intended to be supported.
Use
env1 = sim.Environment()
now.

Compatibility fix (0)
---------------------

When saving a video as .gif, Pythonista required the images2gif module, which has a bug in
the latest version of Pythonista.
As Pythonista has now an updated version of Pillow, saving can and will be done in the same way as
in non Pythonista versions.

23.3.5

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

Compatibility update (0)
------------------------

Due to a change in Pillow 10.0.0, salabim did not work properly with that version:

- font.getsize was deprecated. Salabim now uses font.getbbox.
- Image.ANTIALIAS was deprecated. Salabim now uses Image.LANCZOS
From now on, Pillow >=10.0.0 is also supported.

23.3.4

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

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

A bug in Component.to_stock() fixed.

23.3.3

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

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

In order to check whether a model that runs with sim.yieldless(False)
is not a yieldless model, salabim may under rare circumstances report:
ValueError: process must be a generator (contain yield statements.)
Maybe this a yieldless model. In that case:
- remove sim.yieldless(False)
If it is indeed a yield model, make this process method (and maybe others) into a generator, e.g.
by adding at the end:
return
yield just to make this a generator

So when it is indeed a yieldless model, remove the sim.yieldless(False) statement.
If this is a model with yields, change the process method into a generator, e.g. by adding
yield self.hold(0) added to make this process a generator
or
if False:
yield added to make this process a generator
or (at the end)
return
yield added to make this process a generator


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

The method Store.to_store_requesters() returns a reference to the to requesters, like
Store.from_requesters() that was already in salabim.
These methods can be very useful for animating a store.


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

AnimateGrid used 0 and env.width() for the x-range. And 0 and env.height() for the y-range.
This worked fine as long as screen coordinates were the same as user coordinates.
In order to properly work with user coordinates, the x-range should be env.x0() and env.x1()
and the y-range should be env.y0() and env.y1(). Fixed.

Page 4 of 26

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.