nested scenario outlines in Behat? - behat

Is it possible to have nested scenario outlines in Behat (Gherkin)
e.g. do all of the below for a different set of Examples
Scenario Outline: Some Outline
Given step one with <var1>
When step two with <var2>
Then step three
Examples:
| var1 | var2 |
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |

It's not entirely clear what you mean. The scenario outline you wrote looks fine. It will end up doing the following:
Given step one with 1
When step two with 4
Then step three
Given step one with 2
When step two with 5
Then step three
Given step one with 3
Then step two with 6
Then step three
But it sounds like perhaps you want to do more like this:
Given step one with 1
And step one with 2
And step one with 3
Then step two with 4
And step two with 5
And step two with 6
Then step three
This is where inline tables come into play. You would do:
Scenario: Some Scenario
Given step one
| var |
| 1 |
| 2 |
| 3 |
When step two
| var |
| 4 |
| 5 |
| 6 |
Then step three
You will need to write the "step one" and "step two" steps in the context file to accept a single TableNode argument and iterate over it with foreach(){}.

Related

Best database design to find relationships between two persons

I want to find relationships between two persons using a database. For example, I have a database like this:
Person:
Id| Name
1 | Edvard
2 | Ivan
3 | Molly
4 | Julian
5 | Emily
6 | Katarina
Relationship:
Id| Type
1 | Parent
2 | Husband\Wife
3 | ex-Husband\ex-Wife
Relationships:
Id| Person_1_Id | Person_2_Id | Relation_Id
1 | 1 | 3 | 2
2 | 3 | 4 | 3
3 | 3 | 2 | 1
4 | 4 | 2 | 1
5 | 1 | 6 | 3
6 | 1 | 5 | 1
7 | 6 | 5 | 1
What the best way to find what relationship between Person-2 and Person-5? This example is not large enough, but what if there were 5 families or 10000. I think, if there are too many families, then it is necessary to introduce the concept of depth. Maybe it will be better to change the database design? Is this possible to make it like trees or graphs? Some ideas on how to solve this problem differently?
As soon as you get above a handful of nodes and a few relationships between them, this becomes a very complex problem: there are whole branches of maths based around this type of challenge and how long it takes to compute a result.
For any non-trivial set of nodes/relationships you are going to need to look at deploying a graph database e.g. Neo4j

SQL - Combining all children in one row

I am trying to move data from a database into a pandas data frame. I have data in multiple tables that I want to combine.
I'm using SQLAlchemy and relationship between parent/children.
I'm trying to understand how I'd do this in SQL before attempting in SQLAlchemy
I am using Sqlite as a DB.
parent_table
ID | Name | Class
1 | Joe | Paladin
2 | Ron | Mage
3 | Sara | Knight
child1
ID | distance | finished | parent_id
1 | 2 miles | yes | 1
2 | 3 miles | yes | 1
3 | 1 miles | yes | 1
4 | 10 miles | no | 2
child2
ID | Weight | height | parent_id
1 | 5 lbs | 5'3 | 1
2 | 10 lbs | 5'5 | 2
I want to write a query where the result would be everything for Joe (id: 1) on a row.
1 | Joe | Paladin | 2 miles | yes | 3 miles | yes | 1 miles | yes | 5lbs | 5'3
2 | Ron | Mage | 10 miles | no | None | None | None | None | 10lbs | 5'5
3 | Sara | Knight | None | None | None | None | None | None | None | None
I'm guessing I need to do a join, but confused about the fact that Ron has less child1 entries.
How do I construct a table that has as many columns as needed and fills out the empty ones as None when some of the rows in parent_table don't have as many children?
simply search everyone by themself and use a union to join:
SELECT Name,Class FROM parent_table WHERE ID = 1
UNION
SELECT distance,finished FROM child1 WHERE parent_id = 1
UNION
SELECT weight,height FROM child2 WHERE parent_id =1
This way you avoid the problem for Ron or anyone that does not have a register in a table,
You can't have "As many columns as needed" because the number of child rows is variable and you can't have a variable number of columns. If you can figure out a fixed number of children, (say 2) you can do:
CREATE TABLE
"some_table"
AS
SELECT
"parent_table"."ID",
"parent_table"."Name",
"parent_table"."Class",
"child1_1"."finished" AS "2_miles",
"child1_2"."finished" AS "3_miles"
FROM
"parent_table",
"child1" AS "child1_1",
"child1" AS "child1_2"
WHERE
"child1_1"."parent_id"="parent_table"."id" AND
"child1_2"."parent_id"="parent_table"."id" AND
"child1_1"."distance"='2 miles' AND
"child1_2"."distance"='3 miles'
You can add columns from child2 in the same manner. And child subkeys (data in child1.distance i.e.) will need to go to column names. But for variable one-to-many relations, you need multiple tables. It's basically what the relational concept is all about.
For data analysis (which you are trying to do as it seems) you will also need two datasets (like tables) because the 2 measurements (sample sets) are not correlated (i.e. distances and weights), which you can obtain in 2 tables. Think of what a "sample" is (the result of a measurement). It can't be "entity 1 completed 2 miles and 4lbs" because "2 miles and 4 lbs" it's not a measurable event. So you have 2 distinct samples: "entity 1 completed 2 miles" and "entity 1 completed 4 lbs". (Or are the data in child2 1-to-1 properties of the entity in parent_table ? You should detail better the meaning of the data and what you-re trying to achieve).

How to find articulation points in a graph using SQL

I'm trying to write a Postgres function that returns the results of every articulation point in an undirected graph. But I can't figure out how to do this properly in relation to relational programming. So for example, if the graph is
select * from graph;
source | target
--------+--------
1 | 2
2 | 1
1 | 3
3 | 1
2 | 3
3 | 2
2 | 4
4 | 2
2 | 5
5 | 2
4 | 5
5 | 4
(12 rows)
then the result should be
select articulation_point();
articulation_point
--------------------
2
(1 row)
But I have no idea how to go about this. I've read some articles on how to do this in a programming language like Python, but no idea how to approach it in Postgres.

SQL-design issue - Ordering worker for work teams on a weekly basis

I'm making a web solution using ASP.net MVC6 and Azure SQL-db.
My goal is to make an order system for ordering work teams on a weekly basis and it must be possible to display the work order 6 weeks ahead from todays date. Each work order is connected to a project. A manager should be able to choose a project and then start ordering different kinds of workers (disiplin), assign his need for manpower for each disiplin for 6 weeks ahead. A disiplin can be carpenter, painter, bricklayer etc.
Each project can have any number of disiplin assigned so it's not possible to hard code this into the table structur. You can hardcode the week either as week 2 in 2016 is different from week 2 in 2017
A workorder can look like this:
Project A
Disiplin | Week 1 | Week 2 | Week 3 | Week 4 | Week 5 | Week 6
Carpenter | 4 | 3 | 0 | 0 | 3 | 0
Painter | 0 | 0 | 2 | 3 | 3 | 3
Next project can look like this:
Project B
Disiplin | Week 44 | Week 45 | Week 46 | Week 47 | Week 48 | Week 49
Carpenter | 4 | 3 | 0 | 0 | 3 | 0
Painter | 0 | 0 | 2 | 3 | 3 | 3
Bricklayer| 1 | 2 | 1 | 5 | 3 | 0
Carpentry | 4 | 3 | 0 | 0 | 3 | 0
As you see the week number and number of disiplin may vary from project to project. I can't seem to wrap my head around how to design the SQL-tables to efficently store these values.
Can anyone review this issue and point me in the right direction? Thanks.
EDIT:
The problem is really not to store data but how to query for them. You never know for how many weeks each disiplin has registered data and you don't know how many disiplins registered on each project. In addition for week 2 you may have registered the manpower-needs for Carpenters but not for Painters. I could make a query for each disipline, but I would preferably have one query to get the complete grid.

How to get top 3 frequencies in MySQL?

In MySQL I have a table called "meanings" with three columns:
"person" (int),
"word" (byte, 16 possible values)
"meaning" (byte, 26 possible values).
A person assigns one or more meanings to each word:
person word meaning
-------------------
1 1 4
1 2 19
1 2 7 <-- Note: second meaning for word 2
1 3 5
...
1 16 2
Then another person, and so on. There will be thousands of persons.
I need to find for each of the 16 words the top three meanings (with their frequencies). Something like:
+--------+-----------------+------------------+-----------------+
| Word | 1st Most Ranked | 2nd Most Ranked | 3rd Most Ranked |
+--------+-----------------+------------------+-----------------+
| 1 | meaning 5 (35%) | meaning 19 (22%) | meaning 2 (13%) |
| 2 | meaning 8 (57%) | meaning 1 (18%) | meaning 22 (7%) |
+--------+-----------------+------------------+-----------------+
...
Is it possible to solve this with a single MySQL query?
Well, if you group by word and meaning, you can easily get the % of people who use each word/meaning combination out of the dataset.
In order to limit the number of meanings for each word returned, you will need create some sort of filter per word/meaning combination.
Seems like you just want the answer to your homework, so I wont post more than this, but this should be enough to get you on the right track.
Of course you can do
SELECT * FROM words WHERE word = 2 ORDER BY meaning DESC LIMIT 3
But this is cheating since you need to create a loop.
Im working on a better solution
I believe the problem I had a while ago looks similar. I ended up with the #counter thing.
Note about the problem
Let's suppose there is only one person, who says:
+--------+----------------+
| Person | Word | Meaning |
+--------+----------------+
| 1 | 1 | 7 |
| 1 | 1 | 3 |
| 1 | 2 | 8 |
+--------+----------------+
The report should read:
+--------+------------------+------------------+-----------------+
| Word | 1st Most Ranked | 2nd Most Ranked | 3rd Most Ranked |
+--------+------------------+------------------+-----------------+
| 1 | meaning 7 (100%) | meaning 3 (100%) | NULL |
| 2 | meaning 8 (100%) | NULL | NULL |
+--------+------------------+------------------+-----------------+
The following is not OK (50% frequency is absurd in a population of one person):
+--------+------------------+------------------+-----------------+
| Word | 1st Most Ranked | 2nd Most Ranked | 3rd Most Ranked |
+--------+------------------+------------------+-----------------+
| 1 | meaning 7 (50%) | meaning 3 (50%) | NULL |
| 2 | meaning 8 (100%) | NULL | NULL |
+--------+------------------+------------------+-----------------+
The intended meaning of the frequencies is "How many people think this meaning corresponds to that word"?
So it's not merely about counting "cases", but about counting persons in the table.