How to assign a kind to a group of things - inform7

I'm new to Inform 7. I've been playing around with the 'Bogart' example which provides some rules for clothing.
I have something like:
The player wears a jacket, a jumper, a shirt, some underpants, a pair of men's blue jeans, a pair of socks.
Now I want to add a property to clothing, e.g.:
An item of clothing is a kind of thing.
An item of clothing can be removable. An item of clothing is usually removable.
At this point it looks like I have to go through and explicitly define each item worn by the player as being an item of clothing, such as:
A pair of socks is an item of clothing.
A jumper is an item of clothing.
A jacket is an item of clothing.
...etc for everything the player is wearing.
I would like to find a way to tell Inform that everything worn by the player is an item of clothing or even everything wearable is an item of clothing. So far I haven't found any form of this that will compile, is it possible?

It's not possible. The best you can do is:
The jacket, the jumper, the shirt, the underpants, the pair of men's blue jeans,
and the pair of socks are item of clothing.

Related

How to generate recommendations for a User using Gremlin?

I am using gremlin QL on AWS Neptune Database to generate Recommendations for a user to try new food items. The problem that I am facing is that the recommendations need to be in the same cuisine as the user likes.
We are given with three different types of nodes which are- "User", "the cuisine he likes" and "the category of the cuisine" that it lies in.
In the picture above, the recommendations for "User 2" would be "Node 1" and "Node 2". However "Node 1" belongs to a different category which is why we cannot recommend that node to "User2". We can only recommend "Node 2" to the user since that is the only node that belongs to the same category as the user likes. How do I write a gremlin query to achieve the same?
Note- There are multiple nodes for a user and multiple categories that these nodes belong to.
Here's a sample dataset that we can use:
g.addV('user').property('name','ben').as('b')
.addV('user').property('name','sally').as('s')
.addV('food').property('foodname','chicken marsala').as('fvm')
.addV('food').property('foodname','shrimp diavolo').as('fsd')
.addV('food').property('foodname','kung pao chicken').as('fkpc')
.addV('food').property('foodname','mongolian beef').as('fmb')
.addV('cuisine').property('type','italian').as('ci')
.addV('cuisine').property('type','chinese').as('cc')
.addE('hasCuisine').from('fvm').to('ci')
.addE('hasCuisine').from('fsd').to('ci')
.addE('hasCuisine').from('fkpc').to('cc')
.addE('hasCuisine').from('fmb').to('cc')
.addE('eats').from('b').to('fvm')
.addE('eats').from('b').to('fsd')
.addE('eats').from('b').to('fkpc')
.addE('eats').from('b').to('fmb')
.addE('eats').from('s').to('fmb')
Let's start with the user Sally...
g.V().has('name','sally').
Then we want to find all food item nodes that Sally likes.
(Note: It is best to add edge labels to your edges here to help with navigation.)
Let's call the edge from a user to a food item, "eats". Let's also assume that the direction of the edge (they must have a direction) goes from a user to a food item. So let's traverse to all foods that they like. We'll save this to a temporary list called 'liked' that we'll use later in the query to filter out the foods that Sally already likes.
.out('eats').aggregate('liked').
From this point in the graph, we need to diverge and fetch two downstream pieces of data. First, we want to go fetch the cuisines related to food items that Sally likes. We want to "hold our place" in the graph while we go fetch these items, so we use the sideEffect() step which allows us to go do something but come back to where we currently are in the graph to continue our traversal.
sideEffect(
out('hasCuisine').
dedup().
aggregate('cuisineschosen')).
Inside of the sideEffect() we want to traverse from food items to cuisines, deduplicate the list of related cuisines, and save the list of cuisines in a temporary list called 'cuisinechosen'.
Once we fetch the cuisines, we'll come back to where we were previously at the food items. We now want to go find the related users to Sally based on common food items. We also want to make sure we're not traversing back to Sally, so we'll use simplePath() here. simplePath() tells the query to ignore cycles.
in('eats').
simplePath().
From here we want to find all food items that our related users like and only return the ones with a cuisine that Sally already likes. We also remove the foods that Sally already likes.
out('eats').
where(without('liked')).
where(
out('hasCuisine').
where(
within('cuisineschosen'))).
values('foodname')
NOTE: You may also want to add a dedup() here after out('eats') to only return a distinct list of food items.
Putting it altogether...
g.V().has('name','sally').
out('eats').aggregate('liked').
sideEffect(
out('hasCuisine').
dedup().
aggregate('cuisineschosen')).
in('eats').
simplePath().
out('eats').
where(without('liked')).
where(
out('hasCuisine').
where(
within('cuisineschosen'))).
values('foodname')
Results:
['kung pao chicken']
At scale, you may need to use the sample() or coin() steps in Gremlin when finding related users as this can fan out really fast. Query performance is going to be based on how many objects each query needs to traverse.

How to handle shared entities (e.g. size)

Trying to build a PoC that allows a user to ask something such as "I want a small pizza with a drink". Since drink didn't have a size, I would then prompt for the desired drink size.
Going with the restaurant example, should sizes (small, medium, large) be individual entities (e.g. #small, #medium, #large)? Does it matter that these entities would be used for both pizza size and drink size, or should we have a #pizza_small, #pizza_medium, #drink_small, #drink_medium, etc. entity? With this, I may need a #drink_no_size so I would know that I need to prompt for a size.
Thanks!
One solution to this problem could be that you would create the following entities: #size for general size, #pizza_size for pizza sizes, #drink_size for drink sizes. You could use this then to disambiguate which sizes were specified in the user input. If only general size was specified you'll get entity #size back, if explicit size for pizza or drink would get specified you would also get the particular entity.
The "no size" would be specified by no size entity detected in the user input.
Here is the example entity definition in the csv format.
size,small,tiny,little
size,medium,normal,standard
size,large,big,biggest,gigantic
pizza_size,psmall,small pizza,tiny pizza,little pizza
pizza_size,pmedium,medium pizza,normal pizza,standard pizza
pizza_size,plarge,large pizza,big pizza,biggest pizza,gigantic pizza
drink_size,dsmall,small drink,tiny drink,little drink,short drink
drink_size,dmedium,medium drink,normal drink,standard drink
drink_size,dlarge,large drink,big drink,biggest drink,tall drink,gigantic drink

How would you find the most specific "filter" that matches a document? (determining which market segment a user fits in)

Imagine you have actions setup for when a user is from a certain demographic/market segment. The filters work a bit like a graph, matching for country, region, platform, operating system, and browser.
By default, you will match any value (if you specify US, you match for all users from the US regardless of region, platform, OS, or browser)
If you specify multiple values for any property of the filter it works like an OR (can be any of the values you specified), for the filter to match all the properties must have at least one match or be empty (accept all), essentially an AND operation.
So we can have:
Segment #1:
Countries: United States, Canada
Segment #2:
Countries: United States
Regions: New York
Platform: Tablets
Segment #3
Countries: United States
Browser: Chrome
Segment #4
Countries: United States
Segment #5
Match all (all filters left empty)
Scenario #1
User from Canada on his Tablet
Result: Segment #1
Scenario #2
User from New York, United States visits from Google Chrome on his Tablet.
Result: Segment #2, because the filter more specifically matches the user (matches country, region, and platform)
Scenario #3
User from Texas visits from his desktop
Result: Segment #4, tie with segment #1 is resolved because Segment #4 only matches United States and is therefore more specific
Work so far
I was thinking I could take each segment and load it up into a graph database that looks something like this
Country -> Region -> Platform --> OS -> Browser -> Segment
Each node either has a value (ex: United States, Chrome, Firefox, etc) and relationships that link it to any node below it in the tree (Country -> Browser is okay, Browser -> Country is not) or is null ("match all").
Each relationship (represented by ->) would also store a weight used to resolve ties. Relationships from a catch-all node get the max weight as they will always lose to a more specific filter.
Example database (numbers on the lines are the weight, lower weight becomes the prefered path)
Potential query
So now I need a query (maybe neo4j can do this?) that does the following:
Find the top level country node with the same value as the user or null
Go through each relationship (sorted by weight in ascending order)
Find the longest path, ties go to the node connected by a relationship with the lowest weight (if the tie is between a relationship to a null/catch-all node, the null node loses)
Continue this loop until we find a segment #
I'm sorry for the long post, it's hard to explain what I'm getting at via text.
What I'm looking for
Am I on the right path to solving this problem?
Are there better ways to go about this?
What would be the best way to store these relationships (graph database?)
How can I build a query that does what I want?
tl;dr: Need a way decent/performant way of finding the longest/most specific path in a graph like data structure. Comments requesting clarification or with any related information/documentation/projects/reading are very welcome
With Neo4j, you can store properties in a relationship, example:
(u1:User{name:"foo"})-[:FRIEND_WITH{since : "2015/01/01"}]->(u2:User{name:"bar"})
I think you should store country nodes this way:
(usa:Country{name: "USA", other attributes...})
So you can find every single country by matching with Country label, and then filter with the name property to get the one you're looking for.
Same for the cities, you can do a simple relationship to store every city :
(usa:Country{ name: "USA"})-[:CONTAINS_CITY]->(n:City{name: "New York", other attributes...})
and then you can add platform etc after the city.
To match a segment related to a certain country, you can do this way (example for Scenario #1) :
Match (c:Country{name : "Canada"})-[*1..2]->(p:Platform{name : "Tablet"})-[*1..]->(s:Segment) return s
Then you can create your segment by using nodes and create relations between them, the only problem may be on this case:
User1 has a Tablet in Canada
User2 has a Tablet in Canada using
Chrome
In this case, because of the depth match on the relationship ([*1..]) the User1 can be on the same segment as User2. The solution is to create intermediate nodes with default values, in case you don't have browser informations for example.

Creating view with node reference

I am using drupal 6. please give me idea about how should i create view with below requirements,
There will be list of awards (gold , silver etc)
There will be list of companies who won one of the above award (comp1->gold, comp2->gold, comp3->silver etc)
I need to display list of awards first and when user clicks on any award he will be redirected to page having list of companies who won that award.
I created two content types for Awards and Companies and award_id is used as node reference in Company content type. Please guide further.I am using drupal 6. Thanks.
Fist task (just a simple list of awards is easy - just create a view that displays nodes in "awards" type, order as you want, limit as you want...
Get also node id filed, if it's not available at start, since you gonna need it.
For the second task - create a new view, that will list companies and under arguments add that award id. Then, you should pass award id to page as extra parameter:
/awords/3
Where 3 is award id.
Sorry, Drupal 6 is pretty old and I didn't use it lately, but that's the basic idea.

Designing "hot or not" style database in Entity Framework Model First

I want to design a duel of sorts between movies so that two are pitched against each other, the user selects the better one which then gets a point. In the database I want a list of all movies that have dueled and how many times they have won respectively.
Movie
Id
Name
Duels
Duel
ContenderOne
ContenderTwo
NumberOfDuels
ContenderOneWins
ContenderTwoWins
I'm trying to set this up so that the movie entity has 1 property called Duels in which I can fetch all duel entities where it is involved, regardless of it being contender one or contender two. ContenderOne and ContenderTwo should link back to the movies.
Any ideas how to achieve this? I am stumped.
You can't have just one property. You will need two: DuelsAsContenderOne and DuelsAsContenderTwo. If you need all duels disregarding the position, you can use the expression x.DuelsAsContenderOne.Concat(x.DuelsAsContenderTwo)

Resources