Hi Manuel,
By design, VIKTOR’s call flow is (mostly) stateless, this means that in principle nothing is saved besides the input itself, and the functions to get to the result. The reasoning for this is that we believe that the same input from the user should always return the same result, no matter in what order you see the views. You can find more information about this here.
I think that the variables that you are using such as the vertical deviation are not meant to be user input, but rather intermediary results for the developer? In that case they will indeed be recalculated every time. This can be a bit counter intuitive at first, but it guarantees the statelessness.
I totally understand that you do not want to rewrite all the variables every time, therefore I usually make a model class to make it easier for myself. I use this model to put all my calculations in, and use this model for every view. in your case it might look something like the example below.
As the calculations are fast, it should not have an effect on the user experience that you are calculating the same cosine twice. However, once you start to run large analyses, you might want to look into memoization and storage to avoid full statelessness and store intermediary results.
I hope this helps.
Paulien
import math
from dataclasses import dataclass
# c, L a2x and a2y are user input,
# xS2t, yS2t and bottom_of_pile are calculated
@dataclass
class Pile:
a: float
L: float
a2x: float
a2y: float
def xS2t(self):
return self.a + self.a2x/100
def yS2t(self):
return self.a2x/100
def bottom_of_pile(self):
return self.L * math.tan(2)
def p2(self):
return Point(0, 0, self.L)
in your controller:
@DataView("Calculation output", duration_guess=1)
def my_calculation(self, params, **kwargs):
piles = []
# create one pile object for each row in the table
for row in params.table:
piles.append(Pile(row["a"], row["L"], row["a2x"], row["a2y"]))
data_groups = []
# show the intermediate results for each pile to user
for i, pile in enumerate(piles):
data_groups.append(
DataGroup(
DataItem('Pile', i+1),
DataItem('length', pile.L),
DataItem('bottom of pile', pile.bottom_of_pile()),
)
)
data = DataGroup.from_data_groups(data_groups)
return DataResult(data)
@WebView("Other Calculation output", duration_guess=1)
def my_other_calculation(self, params, **kwargs):
pile = Pile(1, 2, 3, 4)
return WebResult(html=f"A pile with a={pile.a}, L={pile.L}, a2x={pile.a2x} "
f"and a2y= {pile.a2y} will have yS2t = {pile.yS2t()}")
edit: changed column to pile so not to be confusing with table rows and columns