How to generate (not draw/render) sequence diagrams - generator

I'm looking for ways to generate Sequence Diagrams out of programmed Logic. I do not mean rendering them out of e.g. text. A lot of post talk about generating, but I see that as rendering/drawing. I've searched the internet and most found textual tools (like PlantUML) or intuitive graphical payed tools. I'm not looking for either. But I want to program the message flow and let the system draw it based on possible choices. One reason for it is that the conditional if then else with 'alt' is not very useful (my opinion) if the else triggers a whole different path. It works for one different return, but it becomes very ugly soon (again my opinion). The other reason is that I'm busy developing such a generating tool myself and I'm wondering if I do not try the make something nobody is waiting for. Except the fact that it is a nice hobby project for myself. For me it made sense to make it as it Interactively creates the Message Diagrams which are very helpful during the development process or pass on knowledge. Perhaps it could even validate the logic on dead ends. The third reason is that the text becomes complex by itself to maintain (see example below). The fourth reason is that I believe in automating a process that can/should be automated as we should not be busy drawing stuff but writing logic. So is anybody aware of generating (not draw/render) tools available for sequence diagrams?
The following examples were created where the difference started at invalid/valid card, which is difficult to capture in an if/then/else. And even so other choices are made along the way.
Invalid card, choices: electronic -> chip -> invalid card -> keep goods
Merchant Customer Terminal
| | |
+-inform-amount | |
|---choose-method--->| |
|<--chooses-terminal-| |
+-enters-amount | |
|------------start-payment----------->|
| |<--show-amount--|
| +-inserts-card |
| |-method-chosen->|
| |<--card-invalid-|
| +-pay-different |
|<-----------payment-failed-----------|
+-goods-left-behind | |
+-customer-leaves | |
Valid card, choices: electronic -> chip -> valid card -> auth valid -> enough balance
Merchant Customer Terminal Secure-Intf Acc-Srv Acc-DB
| | | | | |
+-inform-amount | | | | |
|----choose-method--->| | | | |
|<--chooses-terminal--| | | | |
+-enters-amount | | | | |
|-------------start-payment------------->| | | |
| |<---show-amount---| | | |
| +-inserts-card | | | |
| |--method-chosen-->| | | |
| |<----card-valid---| | | |
| +-enter-pin | | | |
| |---validate-pin-->| | | |
| | |--sec:authorize-->| | |
| | | |--verify-login-->| |
| | | | |---get-login-details-->|
| | | | |<-----login-details----|
| | | |<-login-response-| |
| | |<--sec:auth-valid-| | |
| | |---sec:transfer-->| | |
| | | |----transfer---->| |
| | | | |------get-balance----->|
| | | | |<-----balance-info-----|
| | | | |-upd-checking-balance->|
| | | | |-upd-merchant-balance->|
| | | | |----commit-changes---->|
| | | | |<---changes-committed--|
| | | |<---transferred--| |
| | |<-sec:transferred-| | |
|<-----------payment-successful----------| | | |
+-goods-given | | | | |
| |<-------paid------| | | |
| +-customer-leaves | | | |
Textual code valid for several free drawing tools. If any changes are needed then I think it becomes difficult to maintain. I rather generate them.
title MSG-Flow for 'Merchant-flows'
participant "Merchant" as Merchant
participant "Customer" as Customer
participant "Terminal" as Terminal
participant "Secure Intf" as Secure_Intf
participant "Acc Srv" as Acc_Srv
participant "Acc DB" as Acc_DB
note left of Merchant: inform-amount
Merchant -> Customer: choose-method
Customer -> Merchant: chooses-terminal
note left of Merchant: enters-amount
Merchant -> Terminal: start-payment
Terminal -> Customer: show-amount
note right of Customer: inserts-card
Customer -> Terminal: method-chosen
Terminal -> Customer: card-valid
note right of Customer: enter-pin
Customer -> Terminal: validate-pin
Terminal -> Secure_Intf: sec:authorize
Secure_Intf -> Acc_Srv: verify-login
Acc_Srv -> Acc_DB: get-login-details
Acc_DB -> Acc_Srv: login-details
Acc_Srv -> Secure_Intf: login-response
Secure_Intf -> Terminal: sec:auth-valid
Terminal -> Secure_Intf: sec:transfer
Secure_Intf -> Acc_Srv: transfer
Acc_Srv -> Acc_DB: get-balance
Acc_DB -> Acc_Srv: balance-info
Acc_Srv -> Acc_DB: upd-checking-balance
Acc_Srv -> Acc_DB: upd-merchant-balance
Acc_Srv -> Acc_DB: commit-changes
Acc_DB -> Acc_Srv: changes-committed
Acc_Srv -> Secure_Intf: transferred
Secure_Intf -> Terminal: sec:transferred
Terminal -> Merchant: payment-successful
note left of Merchant: goods-given
Terminal -> Customer: paid
note right of Customer: customer-leaves
So is anybody aware of generating (not draw/render) tools available for sequence diagrams?

Have you tried ZenUML(https://zenuml.com)?
It can also generate sequence diagram from Java code (as an Intellij Idea plugin).

Related

Search ontology tree by relationships in MySQL

i am working on a MySQL database with the following schema:
In which we save information from different ontologies (exmp). Some of the terms have relationships (exmp: MS:1000004, sample mass) which are indicated by relationship: or is_a:. For the sake of this question let's focus on the is_a relationships.
We now want to provide an option to search along these is_a relationships. So a function which we give MS:1000004/sample mass as input and get in return all Terms which are connected to it by an is_a relationship. But not only all terms directly connected to MS:1000004, but also all terms which are connected to the children and so on. This image describes this a bit better, where thing would be MS:1000004/sample mass and everything below is what i want as result.
Currently we are using a rather unoptimized recursive function as a stored procedure to do this:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `getAllTermsByParentTerm`(IN `parentOntology` varchar(512))
BEGIN
WITH RECURSIVE previous (accession, FK_OntologyName, name, definition, xrefvaluetype, isobsolete, fk_termAccession, relationshiptype, fk_termAccession_related, depth_level) AS (
SELECT
t.accession,
t.FK_OntologyName,
t.name,
t.definition,
t.xrefvaluetype,
t.isobsolete,
trt.fk_termAccession,
trt.relationshiptype,
trt.fk_termAccession_related,
0 depth_level
FROM Term t
INNER JOIN (TermRelationship AS trt, Term AS ref) ON(
t.Accession = trt.FK_TermAccession
AND trt.FK_TermAccession_Related = ref.Accession
AND (trt.RelationshipType = `is_a` OR trt.RelationshipType = `part_of`)
AND
(
trt.FK_TermAccession_Related = ref.Accession
AND ref.Name = parentOntology
)
)
UNION All
SELECT
t2.accession,
t2.FK_OntologyName,
t2.name,
t2.definition,
t2.xrefvaluetype,
t2.isobsolete,
trt2.fk_termAccession,
trt2.relationshiptype,
trt2.fk_termAccession_related,
(previous.depth_level+1) depth_level
FROM Term t2
INNER JOIN (TermRelationship AS trt2, previous) ON(
t2.Accession = trt2.FK_TermAccession
AND trt2.FK_TermAccession_Related = previous.Accession
)
)
SELECT
t.Accession,
t.FK_OntologyName,
t.Name,
t.Definition,
t.xRefValueType,
t.IsObsolete,
p.depth_level
FROM previous p
Inner JOIN Term AS t ON (
p.Accession = t.Accession
);
END$$
DELIMITER ;
To the question: i am not that experienced with MySQL so are there any options to optimize this function, or is MySQL the wrong tool overall?
Example rows:
Term
| Accession | FK_OntologyName | Name | Definition | XRefValueType | IsObsolete |
|------------|-----------------|----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|------------|
| TEST:0000000 | TEST | Proteomics Standards Initiative Mass Spectrometry Vocabularies | "Proteomics Standards Initiative Mass Spectrometry Vocabularies." [PSI:MS] | | 0 |
| TEST:1000001 | TEST | sample number | "A reference number relevant to the sample under study." [PSI:MS] | value-type:xsd\:string "The allowed value-type for this CV term." | 0 |
| TEST:1000002 | TEST | sample name | "A reference string relevant to the sample under study." [PSI:MS] | value-type:xsd\:string "The allowed value-type for this CV term." | 0 |
| TEST:1000003 | TEST | sample state | "The chemical phase of a pure sample, or the state of a mixed sample." [PSI:MS] | | 0 |
| TEST:1000004 | TEST | sample mass | "Total mass of sample used." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000005 | TEST | sample volume | "Total volume of solution used." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000006 | TEST | sample concentration | "Concentration of sample in picomol/ul, femtomol/ul or attomol/ul solution used." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000007 | TEST | inlet type | "The nature of the sample inlet." [PSI:MS] | | 0 |
| TEST:1000008 | TEST | ionization type | "The method by which gas phase ions are generated from the sample." [PSI:MS] | | 0 |
| TEST:1000011 | TEST | mass resolution | "Smallest mass difference between two equal magnitude peaks so that the valley between them is a specified fraction of the peak height." [PSI:MS] | value-type:xsd\:string "The allowed value-type for this CV term." | 0 |
| TEST:1000012 | TEST | resolution measurement method | "Which of the available standard measures is used to define whether two peaks are separate." [PSI:MS] | | 0 |
| TEST:1000014 | TEST | accuracy | "Accuracy is the degree of conformity of a measured mass to its actual value." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000015 | TEST | scan rate | "Rate in Th/sec for scanning analyzers." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000016 | TEST | scan start time | "The time that an analyzer started a scan, relative to the start of the MS run." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 |
| TEST:1000018 | TEST | scan direction | "Direction in terms of m/z of the scan for scanning analyzers (low to high, or high to low)." [PSI:MS] | | 0 |
| TEST:1000019 | TEST | scan law | "Describes the function in control of the m/z scan (for scanning instruments). Commonly the scan function is linear, but in principle any function can be used." [PSI:MS] | | 0 |
| TEST:1000021 | TEST | reflectron state | "Status of the reflectron, turned on or off." [PSI:MS] | | 0 |
| TEST:1000022 | TEST | TOF Total Path Length | "The length of the field free drift space in a time of flight mass spectrometer." [PSI:MS] | value-type:xsd\:float "The allowed value-type for this CV term." | 0 | | value-type:xsd\:int "The allowed value-type for this CV term." | 0 |
TermRelationship
| ID | FK_TermAccession | RelationshipType | FK_TermAccession_Related | FK_OntologyName |
|--------|------------------|------------------|--------------------------|-----------------|
| 0 | TEST:1000001 | is_a | TEST:0000000 | TEST |
| 1 | TEST:1000002 | is_a | TEST:0000000 | TEST |
| 2 | TEST:1000003 | is_a | TEST:1000002 | TEST |
| 3 | TEST:1000004 | is_a | TEST:1000002 | TEST |
| 4 | TEST:1000005 | is_a | TEST:1000002 | TEST |
| 5 | TEST:1000006 | is_a | TEST:1000002 | TEST |
| 6 | TEST:1000007 | is_a | TEST:1000002 | TEST |
| 7 | TEST:1000008 | is_a | TEST:1000007 | TEST |
| 8 | TEST:1000011 | is_a | TEST:1000007 | TEST |
| 9 | TEST:1000022 | is_a | TEST:0000000 | TEST |
Expected outcome is to execute the function for TEST:0000000/Proteomics Standards Initiative Mass Spectrometry Vocabularies and get all the following terms, because they are child/grandchild terms to TEST:0000000.
TEST:1000001
TEST:1000002
TEST:1000003
TEST:1000004
TEST:1000005
TEST:1000006
TEST:1000007
TEST:1000008
TEST:1000011
TEST:1000022
Some of these may help performance:
t: INDEX(Accession)
trt: INDEX(FK_TermAccession_Related, relationshiptype, FK_TermAccession)
trt: INDEX(FK_TermAccession, FK_TermAccession_Related, relationshiptype)
ref: INDEX(Accession, Name)
previous: INDEX(Accession, depth_level)
Please use JOIN...ON instead of (TermRelationship AS trt, Term AS ref)
What table is parentOntology in?
trt.FK_TermAccession_Related = ref.Accession show up redundantly.

pyqt4 - MySQL How print single/multiple row(s) of a table in the TableViewWidget

I've recently tried to create an executable with python 2.7 which can read a MySQL database.
The database (named 'montre') regroups two tables : patient and proto_1
Here is the content of those tables :
mysql> select * from proto_1;
+----+------------+---------------------+-------------+-------------------+-----
----------+----------+
| id | Nom_Montre | Date_Heure | Temperature | Pulsion_cardiaque | Taux
_oxy_sang | Humidite |
+----+------------+---------------------+-------------+-------------------+-----
----------+----------+
| 1 | montre_1 | 2017-11-27 19:33:25 | 22.30 | NULL |
NULL | NULL |
| 2 | montre_1 | 2017-11-27 19:45:12 | 22.52 | NULL |
NULL | NULL |
+----+------------+---------------------+-------------+-------------------+-----
----------+----------+
mysql> select * from patient;
+----+-----------+--------+------+------+---------------------+------------+----
----------+
| id | nom | prenom | sexe | age | date_naissance | Nom_Montre | com
mentaires |
+----+-----------+--------+------+------+---------------------+------------+----
----------+
| 2 | RICHEMONT | Robert | M | 37 | 1980-04-05 23:43:00 | montre_3 | ess
aye2 |
| 3 | PIERRET | Mandy | F | 22 | 1995-04-05 10:43:00 | montre_4 | ess
aye3 |
| 14 | PIEKARZ | Allan | M | 22 | 1995-06-01 10:32:56 | montre_1 | Hea
lthy man |
+----+-----------+--------+------+------+---------------------+------------+----
----------+
As I'm just used to code in C (no OOP), I didn't create class in the python project (shame on me...). But I managed, in two files, to create something (with mysql.connector) which can print (on the cmd) my database and excecute sub like looking-for() etc.
Now, I want to create a GUI for users with pyqt. Unfortunately, I saw that the structure is totally different, with class etc. But okay, I tried to go throught this and I've created a GUI which allows to display the table "patient". But I didn't manage (in the datasheet of QT) to find how I can use the programs I've already created to display. Neither how to display in a tableWidget only several rows of my table patient for exemple (Using QSQL).
For example, if I want to display all the table patient, I use this line (pyQt):
self.model.setTable("patient")
For this one, I got it, but that disturb me because there is no MySQL coding requisites to display my table and so I don't know how to sort only the rows we want to see and display them. If we only want to see, for example, the ID n°2, how to display in the table:widget only Robert ?
To recap, I want to know :
If I can take the coding I've created and combine it with pyQT
How to display (tableWidget) only rows which are selected by MySQL. Is that possible ?
Please find in the URL my code for a better understanding of my problem :
https://drive.google.com/file/d/1nxufjJfF17P5hN__CBEcvrbuHF-23aHN/view?usp=sharing
I hope I was clear, thank you all for your help !

How to Store Ad Campaign Rules in a database to Query Efficiently?

I have a MySQL table like below which contains thousands of advertising campaigns.
+---------+--------------+------------------+--------------+-------------------+---------------------+
| int: id | string: name | json: countries | json:regions | json: platforms | json: browsers |
+---------+--------------+------------------+--------------+-------------------+---------------------+
| 1 | Uber Android | ["US","UK","DE"] | | ["Android"] | |
+---------+--------------+------------------+--------------+-------------------+---------------------+
| 2 | Game X | ["US"] | | ["Android","iOS"] | ["Chrome","Safari"] |
+---------+--------------+------------------+--------------+-------------------+---------------------+
| 3 | Game Y | | | ["Android"] | |
+---------+--------------+------------------+--------------+-------------------+---------------------+
In this table, an empty column means it supports all options (e.g. an empty country means the campaign is available for all countries). So basically when I get a visitor, I can extract user details like country code, region, platform, browser and I want to find all suitable ad campaigns matching to user.
So my question is what's the best approach to store this data for querying for each visitor to get the list of all matching campaign IDs?

MySQL -> HTML Report, Styled like a Pivot Table

Ok, I'd like to start off by apologizing (profusely), since this seems to be a common question. Most of the examples seem to be somewhat similar, as well, but - for the life of me, I cannot wrap my brain around how to apply the myriad of quality responses to my specific table. And, I'm sure it's probably just the easiest thing in the world, what with all the very thorough responses/examples/links to resources with explanations/etc.
So, I suppose I'll just get right to it. The basics:
We host off-site copies of our clients' backups.
We need to know how much space they're using.
We are not at all consistent in Naming Convention, folder vs. disk per client, etc.
We need to automate a 'report', monthly, with data as follows:
-[C.Srv 01]---Size(GB)--Free(%)
Client 01 [Total] [AVG]
Server 01 109.43 25
Server 02 415.19 25
WHERE C.Srv = [Specified Cloud Server]
Clients Get a Total Size(GB) and an Average Free(%)
My MySQL table is this:
# Name DataType Length/Set Unsigned Allow NULL ZeroFill Default
1. ID INT 11 AUTO_INCREMENT
2. Client TEXT
3. Server TEXT
4. C.Srv TEXT
5. Size DECIMAL 10,2
6. Free DECIMAL 10,4
So, for Example, let's say I have this...
___ ________ ________ _________ _________ _______
ID | CLIENT | SERVER | C.SRV | SIZE | FREE
---|--------|--------|---------|---------|-------
1 | a | adc | cs_01 | 109.43 | 0.2504
2 | a | asql | cs_01 | 415.19 | 0.2504
3 | b | bdc | cs_01 | 583.91 | 0.1930
4 | b | bdev | cs_01 | 316.52 | 0.1930
5 | b | bsql | cs_01 | 1259.56 | 0.1930
6 | c | cdc | cs_01 | 355.30 | 0.7631
7 | d | ddc | cs_01 | 398.21 | 0.5808
Is it possible to get something pretty, in HTML (preferably), that has the basic structure of this...
_______ __________ ________
CS_01 | Size(GB) | Free(%)
-------|----------|--------
-a | 524.62 | 25.04%
-------|----------|--------
adc | 109.43 | 25.04%
asql | 415.19 | 25.04%
-b | 2178.88 | 19.30%
-------|----------|--------
bdc | 583.91 | 19.30%
bdev | 316.52 | 19.30%
bsql | 1259.56 | 19.30%
+c | 355.30 | 76.31%
-------|----------|--------
+d | 398.21 | 58.08%
_______|__________|________
Or, am I just S.O.L.? Format, I can mess with in CSS, or whatever (I hope), just so long as it's in that basic structure. (I don't know if it matters, but the final goal will be to collapse at the Client Level; in case that somehow factors into the approach/data-gathering.)

Multiple Data Sources in Microsoft Excel SQL Query

I have a lot of spreadsheets that pull transactional information from our ERP software into Excel using the Microsoft Query that we then perform other calculations on automatically. Recently we upgraded our ERP system, but management made the decision to leave the transactional history in the old databases to have a clean one going forward in the new system. I still need to have some "rolling 12 months" graphs, but if I use only the old database, I'm missing new data and if I use only the new, I'm missing the last 11 months data.
Is there a way that I can write a query in Excel to pull data from the old database PartTran table and merge it with the new database PartTran table without user intervention each time? For instance, I don't want my users (if possible) to have to have two queries that they copy and paste into one Excel table. The schema of the tables (at least the columns I need) are identically named and defined.
If you want to take a bit of a fun, hacky Excel approach, you could do the "copy-paste" bit FOR your users behind the scenes. Given two similar tables OLD and NEW with structures
+-----+------+-------+------------+
| id | foo | bar | date |
+-----+------+-------+------------+
| 95 | blah | $25 | 2015-06-01 |
| 96 | bork | $12 | 2015-07-01 |
| 97 | bump | $200 | 2015-08-01 |
| 98 | fizz | | 2015-09-01 |
| 99 | buzz | $50 | 2015-10-01 |
| 100 | char | ($1) | 2015-11-01 |
| 101 | mope | | 2015-12-01 |
+-----+------+-------+------------+
and
+----+-----+-------+------------+------+---------+
| id | foo | bar | date | fizz | buzz |
+----+-----+-------+------------+------+---------+
| 1 | cat | ($10) | 2016-01-01 | 285B | 1110111 |
| 2 | dog | $25 | 2016-02-01 | 27F5 | 1110100 |
| 3 | ant | $100 | 2016-03-01 | 1F91 | 1001111 |
+----+-----+-------+------------+------+---------+
... you can union together the data for these two datasets with some prudent excel wizardry as below:
Your UNION table ( named using alt+j+t+a ) should have the following items:
New natural ID
DataSet pointer ( name of old or new table )
Derived ID from original dataset
Columns of data you want from Old & New DataSets
example:
+---------+------------+------------+----+------+-----+------------+------+------+
| UnionId | SourceName | SourceRank | id | foo | bar | date | fizz | buzz |
+---------+------------+------------+----+------+-----+------------+------+------+
| 1 | OLD | | | | | | | |
| 2 | NEW | | | | | | | |
+---------+------------+------------+----+------+-----+------------+------+------+
You will then make judicious use of Indirect() and VlookUp() to derive the lookup id and column targets. Sample code below
SourceRank - helper column
=COUNTIFS([SourceName],[#SourceName],[UnionId],"<="&[#UnionId])
id - the id from the original DataSet
=SMALL(INDIRECT([#SourceName]&"[id]"),[#SourceRank])
Everything else is just VlookUp madness!! Although I've taken the liberty of copying the sample code below for reference
foo =VLOOKUP([#id],INDIRECT([#SourceName]),MATCH(UNION[[#Headers],[foo]],INDIRECT([#SourceName]&"[#Headers]"),0),0)
bar =VLOOKUP([#id],INDIRECT([#SourceName]),MATCH(UNION[[#Headers],[bar]],INDIRECT([#SourceName]&"[#Headers]"),0),0)
date =VLOOKUP([#id],INDIRECT([#SourceName]),MATCH(UNION[[#Headers],[date]],INDIRECT([#SourceName]&"[#Headers]"),0),0)
fizz =VLOOKUP([#id],INDIRECT([#SourceName]),MATCH(UNION[[#Headers],[fizz]],INDIRECT([#SourceName]&"[#Headers]"),0),0)
buzz =VLOOKUP([#id],INDIRECT([#SourceName]),MATCH(UNION[[#Headers],[fizz]],INDIRECT([#SourceName]&"[#Headers]"),0),0)
Output
You'll likely want to make prudent use of If() and/or IfError() to help your users ignore the new column references to the old table and those rows that do not yet have data. Without that, however, you'll end up with something like the below.
This is both ready to accept & read new inputs to both OLD and NEW DataSets and is sortable to get rid of those pesky placeholder rows...
Hope this helps! Happy coding!