Nested fragments UML understanding? - uml

I have a UML book and I am reading about nested fragments. It shows an example of a nested fragment. But what I dont get.. why does it say "If the condition "cancelation not sucessful" is true when entering this fragment (i.e. cancelation was unsuccesful) the interaction within this fragment is no longer executed".
What I have learned before is that a condition should be true before the interaction will be executed? But in this case it says the opposite of it.. (because they say it should be false to execute the interaction)
See for the image: https://ibb.co/CmstLcX

I think this is simply a typo in the book. The diagram makes sense, but the text describes nonsense. While the condition is true, the messages in the loop will happen up to three times.
Maybe the author got confused, because the message immediately before the loop is Cancellation. I assume the loop guard is referring to the success of the Order cancellation message, not to this Cancellation.
By the way, reply messages need to have the name of the original message. Most people get this wrong (and some textbooks). I'll grant that the text on the reply message is often meant to be the return value. As such it should be separated with a colon from the name of the message. In your case it is probably not necessary to repeat the message name, even though techically required. However, the colon is mandatory.
If it is the return value, all reply messages in the loops return the value Acceptance. I wonder, how the guard can then evaluate to true after the first time. Maybe it is only showing the scenario for this case. This is perfectly Ok. A sequence diagram almost never shows all possible scenarios. However, then the loop doesn't make sense. I guess the author didn't mean to return a specific value.
Or maybe it is the assignment target. In this case, it should look like this: Acceptance=Order Cancellation. Then the Acceptance attribute of the Dispatcher Workstation would be filled with whatever gets returned by the Order Cancellation message. Of course, then I would expect this attribute to be used in the guard, like this [not Acceptance].
A third possiblity is, that the author didn't mean synchroneous communication and just wanted to send signals. The Acceptance Signal could well contain an attribute Cancellation not successful. Then of course, no filled arrows and no dashed lines.
I can even think of a fourth possibility. Maybe the author wanted to show the name of an out parameter of the called operation. But this would officially look like this: Order Cancellation(Acceptance). Again the name of the message could be omitted, but the round brackets are needed to make the intention clear.
I think the diagram leaves a lot more questions open than you asked.

It only says "If the cancellation was not successful then" (do exception handling). This is pretty straight forward. if not false is the same as if true. Since it is within a Break fragment, this will be performed (with what ever is inside) and as a result will break the fragment where it is contained (usually some loop). Having a break just stand alone seems a bit odd (not to say wrong).
UML 2.5 p. 581:
17.6.3.9 Break
The interactionOperator break designates that the CombinedFragment represents a breaking scenario in the sense that the operand is a scenario that is performed instead of the remainder of the enclosing InteractionFragment. A break operator with a guard is chosen when the guard is true and the rest of the enclosing Interaction Fragment is ignored. When the guard of the break operand is false, the break operand is ignored and the rest of the enclosing InteractionFragment is chosen. The choice between a break operand without a guard and the rest of the enclosing InteractionFragment is done non-deterministically.
A CombinedFragment with interactionOperator break should cover all Lifelines of the enclosing InteractionFragment.
Except for that: you should not take fragments too serious. Graphical programming is nonsense. You make only spare use of any such constructs and only if they help understanding certain behavior. Do not get tempted to re-document existing code this way. Code is much more dense and better to read. YMMV

Related

UML fragment to prevent the further executions?

What is a UML fragment is using in a case representing a check operation that either stops the further execution on a failed check or lets it go, kind of a programming statement if role != 'admin': break:?
I found the assert fragment seems to fit the case.
The idea on a diagram:
Is the fragment used properly to represent that operation change_sensetive_settings() is executing only if a user has admin role?
I'm not a big fan of assert, which seems to be meant for visual procedureal programming rather than clean design of valid behavior. There is not much information on assert fragment in the standard:
The interactionOperator assert designates that the CombinedFragment represents an assertion. The sequences of the operand of the assertion are the only valid continuations. All other continuations result in an invalid trace.
But the way assert is used here, seems confusing in this regard: you just show a constraint { user.role == 'admin } on the server lifeline, whereas the continuation will result in a message being initiated on the client side.
To disambiguate this diagram, I'd recommend to enclose in the assert fragment the sequence made of the register_user() message, followed by the return message and your constraint. This would clearly relate the outcome regarding the user role constraint to the registration.
But this only tells a part of the story. Because, what does it mean in pratice that "All other continuations result in an invalid trace" ? Assert, just tells an assumption. Is there anything ahead of this interaction that makes this assumption realistic? If not what should happen if the user has insufficient authorisations?
For all these reasons, I'd rather recommend to use here and alt to show the normal flow, but also suggest that if the user does not have the right authorisation, something should happen (and on which side: client or server).
No, I think assert is not used correctly. Here is why:
The specification defines:
The interactionOperator assert designates that the CombinedFragment
represents an assertion. The sequences of the operand of the assertion
are the only valid continuations. All other continuations result in an
invalid trace.
That means, the state invariant {user.role='admin'} is the only valid continuation after the reply to the register_user() message. This would rule out other outcomes. I don't think, this is what you had in mind.
So, simply remove the assert fragment. Since the sequence diagram only shows one possible scenario, it doesn't mean, that other scenarios are not valid. You could have another sequence diagram, where the state invariant is {user.role='student'}.
If you want to show more scenarios in one diagram, you could use an alt fragment. However, as others have pointed out, the purpose of the sequence diagram is not visual programming. Therefore, striving for a complete description of all possible scenarios is not appropriate.
minor mistakes
There are some minor mistakes in the diagram. Most of them have been pointed out by others, but to make this a complete answer:
The first message could be a found message. Then the circle would be filled and the name of the message would be on the arrow. It could also come from a gate. This would be shown by originating the arrow from the frame. I would recommend the latter.
The state invariant should probably move down below the reception of change_sensitive_settings because the user could still try to change them. Only the server can decide to reject this request. Or it must move to the client lifeline, if you want to specify that the client only sends the message, if s/he is an admin.
The arrow at the end of the diagram should be dashed, since it is the reply to the synchronuous message it begins with. And again, it should end in a black circle denoting a lost message or, better, at the frame of the diagram.

Pyparsing will always insert a list on 'setParseAction'

Apparently if you add any parse action and return a result in that action, the result will always be encapsulated into a list 'deepening' the output tree.
I suppose this is for returning multiple values but it makes casual use of the library far harder because you then have to remember which parts of the tree you replaced and call result.normalstruct.replaced[0] (or even worse result.normalstruct['replaced'][0])
This is a bit strange and makes refactoring harder, so i'd like a way to avoid it. Any tips?
The problem here is that the argument token of setParseAction is already a list. Instead of operating on str(token_argument) i should operate on str(token_argument[0]) and return that. No more deepening.
edit: though apparently it doesn't happen always. Happened to me with a word action but when i tried to 'unwrap' element zero of a 'And' expression result from a setParseAction functor it gave me the first subexpression.
Man, i'd like consistency here.

UML activity diagram for showing a two-pass algorithm

I want to show use of same algorithm as a black box in two-pass iteration. In first pass, I would pass a value of a flag f as false, and an array of one element as A[1..1], output of first pass would be B[1..N]. In second pass, same algorithm would be used with f as true (to indicate second pass) with an input of A[1..N] (fed from output B[1..N] of first pass) whereas the output of second pass would be B[1..M]
Please help me drawing the UML Activity diagram for the same.
It's not a good idea to try "programming graphically". The algorithm you describe is better shown in meta code than in an activity diagram, as you already have seen. So what I'd do in your case is to have a single Action (representing most likely some CallOperation of some class. And the according behavior of the operation contains the description in either meta code or plain text (as you already stated above).
If for what reason ever you really want to "program graphically" you would need to use single actions for the assignments of the flag like this:
The A and B arrays would be just mentioned in the description of the single actions.
To actually show passing the A and B arrays you would need to add ActionsPins or Objects with ObjectFlows between the single Actions. Honestly, that would make the whole thing even more unreadable and hinder more than helping the reader:

break / stop execution in UML sequence diagram mid-way inside alt / opt

In a UML Sequence Diagram - If a flow should stop if a condition is met midway, how would it be best represented with alternate / optional fragments?
i.e. -
If the stop condition is not met then the flow is continued for several more steps.
Should the alternate fragment cover all of the steps since the stop condition, making all steps past it part of the alternate fragment, or is there a notation to handle the stop inside a small alternate fragment (confined only to the condition)?
There are three options for this situation. Each of them I illustrate with a diagram showing how the respective combined fragment should be used. The actual behaviour is hidden with interaction references (normalFlow for a flow that should normally be executed and breakFlow for any flow that should happen in case of a required break).
The first solution is the most convenient one - it exactly covers your case and you can also use the positive version of a break guard. However each of them provide you a valid possibility.
Break combined fragment
When a break combined fragment is met and its guard condition is true, only this fragment is still executed and then the execution of the interaction (flow) stops. If the condition is not met, the combined fragment is omitted and the normal flow continues. This is exactly the case you describe. In this case you would put the messages that shouldn't be executed in case of a break condition after the break combined fragment.
Opt combined fragment
When an opt combined fragment is met it executes only if a guard condition is true. The rest of a flow continues regardless of the condition.
You can put the part of the flow that is continued only if the break condition is not met inside the opt combined fragment. The opt fragment should have a guard that is opposite to the condition at which the flow should stop. If any additional actions should happen in case of a break, they should be put after the opt combined fragment.
Alt combined fragment
When an alt combined fragment is met its guard conditions are evaluated and only the eventual one fragment which guard evaluates to true is executed. There might be also a situation when none of the guards evaluate to true and no fragment is executed in such case. Whatever flow is after the combined fragment is executed normally anyway.
In this case you would preferably put two fragments, one with the correct operation guard and the second one with a condition that should cause a break. Put the normal flow in the first fragment and whatever should happen in case of a break in the second fragment.
You could shortcut the whole thing by using an opt fragment:
One could start arguing that this is syntactically incorrect, but it transports the message (I guess). And that is what counts.
From my personal experience: use fragments as few as possible. Rather split your scenarios to focus on the certain important aspects. A SD is a snapshot of the system at a place where you want an overview over what's going on and not a detailed roadmap with each possible cat and dog trail.

Programming style question on how to code functions

So, I was just coding a bit today, and I realized that I don't have much consistency when it comes to a coding style when programming functions. One of my main concerns is whether or not its proper to code it so that you check that the input of the user is valid OUTSIDE of the function, or just throw the values passed by the user into the function and check if the values are valid in there. Let me sketch an example:
I have a function that lists hosts based on an environment, and I want to be able to split the environment into chunks of hosts. So an example of the usage is this:
listhosts -e testenv -s 2 1
This will get all the hosts from the "testenv", split it up into two parts, and it is displaying part one.
In my code, I have a function that you pass it in a list, and it returns a list of lists based on you parameters for splitting. BUT, before I pass it a list, I first verify the parameters in my MAIN during the getops process, so in the main I check to make sure there are no negatives passed by the user, I make sure the user didnt request to split into say, 4 parts, but asking to display part 5 (which would not be valid), etc.
tl;dr: Would you check the validity of a users input the flow of you're MAIN class, or would you do a check in your function itself, and either return a valid response in the case of valid input, or return NULL in the case of invalid input?
Obviously both methods work, I'm just interested to hear from experts as to which approach is better :) Thanks for any comments and suggestions you guys have! FYI, my example is coded in Python, but I'm still more interested in a general programming answer as opposed to a language-specific one!
Good question! My main advice is that you approach the problem systematically. If you are designing a function f, here is how I think about its specification:
What are the absolute requirements that a caller of f must meet? Those requirements are f's precondition.
What does f do for its caller? When f returns, what is the return value and what is the state of the machine? Under what circumstances does f throw an exception, and what exception is thrown? The answers to all these questions constitute f's postcondition.
The precondition and postcondition together constitute f's contract with callers.
Only a caller meeting the precondition gets to rely on the postcondition.
Finally, bearing directly on your question, what happens if f's caller doesn't meet the precondition? You have two choices:
You guarantee to halt the program, one hopes with an informative message. This is a checked run-time error.
Anything goes. Maybe there's a segfault, maybe memory is corrupted, maybe f silently returns a wrong answer. This is an unchecked run-time error.
Notice some items not on this list: raising an exception or returning an error code. If these behaviors are to be relied upon, they become part of f's contract.
Now I can rephrase your question:
What should a function do when its caller violates its contract?
In most kinds of applications, the function should halt the program with a checked run-time error. If the program is part of an application that needs to be reliable, either the application should provide an external mechanism for restarting an application that halts with a checked run-time error (common in Erlang code), or if restarting is difficult, all functions' contracts should be made very permissive so that "bad input" still meets the contract but promises always to raise an exception.
In every program, unchecked run-time errors should be rare. An unchecked run-time error is typically justified only on performance grounds, and even then only when code is performance-critical. Another source of unchecked run-time errors is programming in unsafe languages; for example, in C, there's no way to check whether memory pointed to has actually been initialized.
Another aspect of your question is
What kinds of contracts make the best designs?
The answer to this question varies more depending on the problem domain.
Because none of the work I do has to be high-availability or safety-critical, I use restrictive contracts and lots of checked run-time errors (typically assertion failures). When you are designing the interfaces and contracts of a big system, it is much easier if you keep the contracts simple, you keep the preconditions restrictive (tight), and you rely on checked run-time errors when arguments are "bad".
I have a function that you pass it in a list, and it returns a list of lists based on you parameters for splitting. BUT, before I pass it a list, I first verify the parameters in my MAIN during the getops process, so in the main I check to make sure there are no negatives passed by the user, I make sure the user didnt request to split into say, 4 parts, but asking to display part 5.
I think this is exactly the right way to solve this particular problem:
Your contract with the user is that the user can say anything, and if the user utters a nonsensical request, your program won't fall over— it will issue a sensible error message and then continue.
Your internal contract with your request-processing function is that you will pass it only sensible requests.
You therefore have a third function, outside the second, whose job it is to distinguish sense from nonsense and act accordingly—your request-processing function gets "sense", the user is told about "nonsense", and all contracts are met.
One of my main concerns is whether or not its proper to code it so that you check that the input of the user is valid OUTSIDE of the function.
Yes. Almost always this is the best design. In fact, there's probably a design pattern somewhere with a fancy name. But if not, experienced programmers have seen this over and over again. One of two things happens:
parse / validate / reject with error message
parse / validate / process
This kind of design has one data type (request) and four functions. Since I'm writing tons of Haskell code this week, I'll give an example in Haskell:
data Request -- type of a request
parse :: UserInput -> Request -- has a somewhat permissive precondition
validate :: Request -> Maybe ErrorMessage -- has a very permissive precondition
process :: Request -> Result -- has a very restrictive precondition
Of course there are many other ways to do it. Failures could be detected at the parsing stage as well as the validation stage. "Valid request" could actually be represented by a different type than "unvalidated request". And so on.
I'd do the check inside the function itself to make sure that the parameters I was expecting were indeed what I got.
Call it "defensive programming" or "programming by contract" or "assert checking parameters" or "encapsulation", but the idea is that the function should be responsible for checking its own pre- and post-conditions and making sure that no invariants are violated.
If you do it outside the function, you leave yourself open to the possibility that a client won't perform the checks. A method should not rely on others knowing how to use it properly.
If the contract fails you either throw an exception, if your language supports them, or return an error code of some kind.
Checking within the function adds complexity, so my personal policy is to do sanity checking as far up the stack as possible, and catch exceptions as they arise. I also make sure that my functions are documented so that other programmers know what the function expects of them. They may not always follow such expectations, but to be blunt, it is not my job to make their programs work.
It often makes sense to check the input in both places.
In the function you should validate the inputs and throw an exception if they are incorrect. This prevents invalid inputs causing the function to get halfway through and then throw an unexpected exception like "array index out of bounds" or similar. This will make debugging errors much simpler.
However throwing exceptions shouldn't be used as flow control and you wouldn't want to throw the raw exception straight to the user, so I would also add logic in the user interface to make sure I never call the function with invalid inputs. In your case this would be displaying a message on the console, but in other cases it might be showing a validation error in a GUI, possibly as you are typing.
"Code Complete" suggests an isolation strategy where one could draw a line between classes that validate all input and classes that treat their input as already validated. Anything allowed to pass the validation line is considered safe and can be passed to functions that don't do validation (they use asserts instead, so that errors in the external validation code can manifest themselves).
How to handle errors depends on the programming language; however, when writing a commandline application, the commandline really should validate that the input is reasonable. If the input is not reasonable, the appropriate behavior is to print a "Usage" message with an explanation of the requirements as well as to exit with a non-zero status code so that other programs know it failed (by testing the exit code).
Silent failure is the worst kind of failure, and that is what happens if you simply return incorrect results when given invalid arguments. If the failure is ever caught, then it will most likely be discovered very far away from the true point of failure (passing the invalid argument). Therefore, it is best, IMHO to throw an exception (or, where not possible, to return an error status code) when an argument is invalid, since it flags the error as soon as it occurs, making it much easier to identify and correct the true cause of failure.
I should also add that it is very important to be consistent in how you handle invalid inputs; you should either check and throw an exception on invalid input for all functions or do that for none of them, since if users of your interface discover that some functions throw on invalid input, they will begin to rely on this behavior and will be incredibly surprised when other function simply return invalid results rather than complaining.

Resources