Recently, I started to study owlready, and faced with much problem.
I defined a PropertyChain as follows.
class friend(Person >> Person, SymmetricProperty):
pass
class potentialFriend(Person >> Person):
# potentialFriend := friend o friend
equivalent_to = PropertyChain([friend, friend])
I tried to get person.potentialFriend.indirect(), but failed. I read the source codes, since the doc on web is too simple, and found that PropertyChain works like a list, I thought it returned a Property. How do I compliment what I want?
How do you use PropertyChain? Is there some concrete examples.
PS: The source codes(.py files) indent with only two whitespaces, :o!
You can use:
P.property_chain.append(PropertyChain([P1, P2]))
...where P1 and P2 are already created ObjectProperties. In your case, P is potentialFriend. P1 and P2 are both friend.
For the reasoner to infer the property chain, don't forget to set its parameter infer_property_values to True :
sync_reasoner(infer_property_values = True)
After that, the reasoner manages to infer the property and you can get it with person.potentialFriend.indirect().
Related
I want to mock this function:
def self.set_segment_info(segment_info, history_record)
history_record.segment_info = segment_info
end
In my test, I want a mock that only confirms that I called set_segment_info with an expected value. I don't care about what I pass in for history_record.
How would I do this? I tried
SegmentHistoryRecord.expects(:set_segment_info).with(:segment_info => expected_segment_info, :history_record => anything)
But that doesn't work.
I ran into this today and ended up doing something like:
SegmentHistoryRecord.expects(:set_segment_info).with(
expected_segment_info,
anything
)
I find it more readable that the do version and it helped me avoid a rubocop issue with too many parameters.
Here's an implementation where, if your function takes a lot of parameters, it's more convenient to specify a value for just the one you care about, instead of for all of them:
expected_segment_info = # ...
SegmentHistoryRecord.expects(:set_segment_info).with() { |actual_parameters| actual_parameters[:segment_info] == expected_segment_info }
(Where, as in the original question, set_segment_info is the function being mocked, and segment_info is the parameter whose value you want to match. Note that the history_record parameter -- and any others that might be present -- don't need to be included.)
SegmentHistoryRecord.expects(:set_segment_info).with() do |param1, param2|
# change below to your verification for :segment_info
# and leave param2 doing nothing, the expectation will ignore param2
param1 == expected_segment_info
end
I know that with Descriptive programming you can do something like this:
Browser("StackOverflow").Page("StackOverflow").Link("text:=Go To Next Page ", "html tag:=A").Click
But is it possible to create some kind of string so I can assign more than one data value and pass it as single variable? I've tried many combinations using escape characters and I always get error.
For example in the case above, let's say I have more properties in the Page object, so I'd normally have to do something like this:
Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")...etc...
But I'd like to pass "name:=StackOverflow", "html id:=PageID" as a single variable, so when writing many objects I'd only have to write:
Browser(BrowserString).Page(PageString).WebEdit("name:=asdfgh")
And the first part would remain static, so if the parents' data needs to be modified I'd only have to modify two variables and not all the objects created in all libraries.
Is it possible?
If I was not clear enough please let me know.
Thank you in advance!
I think what you're looking for is UFT's Description object
This allows you finer grained control on the description since in descriptive programming all values are regular expressions but with Description you can turn the regular expression functionality off for a specific property.
Set desc = Description.Create()
desc("html tag").Value = "A"
desc("innertext").Value = "More information..."
desc("innertext").RegularExpression = False
Browser("Example Domain").Navigate "www.example.com"
Browser("Example Domain").Page("Example Domain").WebElement(desc).Click
If you want to represent this with plain string then it's a bit more of a problem, you can write a helper function but I'm not sure I would recommend it.
Function Desc(descString)
Set ret = Description.Create()
values = Split(descString, "::")
For Each value In values
keyVal = Split(value, ":=")
ret(keyVal(0)).Value = keyVal(1)
Next
Set Desc = ret
End Function
' Usage
Browser("StackOverflow").Page("StackOverflow").WebElement(Desc("html tag:=H2::innertext:=some text")).Click
Further reading about descriptive programming.
As an alternative to Motti's excellent answer, you could also Set a variable to match your initial descriptive object and then extend it as required:
Set myPage = Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")
after which you can then use
myPage.WebEdit("name:=asdfgh")
throughout the rest of the code, so long as the myPage object stays in scope...
I am new to Ruby, so let me describe the context of my problem first:
I have a json as input which has the following key / value pair:
{
"service": "update"
}
The value has many different values for example: insert,delete etc.
Next there is a method x which handles the different requests:
def x(input)
case input[:service]
services = GenericService.new
when "update"
result = services.service(UpdateService.new,input)
when "insert"
result = services.service(InsertService.new,input)
when "delete"
result = services.service(DeleteService.new,input)
....
....
else
raise "Unknown service"
end
puts JSON.pretty_generate(result)
end
What is bothering me is that I still need to use a switch statement to check the String values (reminds me of 'instance of' ugh..). Is there a cleaner way (not need to use a switch)?
Finally I tried to search for an answer to my question and did not succeed, if however I missed it feel free to comment the related question.
Update: I was thinking to maybe cast the string to the related class name as follows: How do I create a class instance from a string name in ruby? and then call result = services.services(x.constantize.new,input) , then the class names ofcourse needs to match the input of the json.
You can try something like:
def x(input)
service_class_name = "#{input[:service].capitalize}Service"
service_class = Kernel.const_get(service_class_name)
service_class.new(input).process
end
In addition you might want to check if this is a valid Service class name at all.
I don't understand why you want to pass the service to GenericService this seems strange. let the service do it's job.
If you're trying to instatiate a class by it's name you're actually speaking about Reflection rather than Polymorphism.
In Ruby you can achieve this in this way:
byName = Object.const_get('YourClassName')
or if you are in a Rails app
byName= 'YourClassName'.constantize
Hope this helps
Just first thoughts, but you can do:
eval(services.service("#{input[:service].capitalize}Service.new, #{input})") if valid_service? input[:service]
def valid_service?
w%(delete update insert).include? input[:service]
end
As folks will no doubt shout, eval needs to be used with alot of care
I'm new here but I hope someone can help me.
I'm developing a Prolog-like DSL for an university project.
This is a simplified grammar that I use to expertiment stuff:
grammar it.unibo.gciatto.Garbage hidden (SL_COMMENT, ML_COMMENT, WS, ANY_OTHER)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate garbage "http://www.unibo.it/gciatto/Garbage"
PTheory returns Theory
: (kb+=PExpression '.')*
;
PExpression returns Expression
: PRule
;
PRule returns Expression
: PConjunction ({ Expression.left=current } name=':-' right=PConjunction)?
;
PConjunction returns Expression
: PExpression0 ({ Expression.left=current } name=',' right=PConjunction)?
;
PExpression0 returns Expression
: PTerm
| '(' PExpression ')'
;
PTerm returns Term
: PStruct
| PVariable
| PNumber
;
PVariable returns Variable
: { AnonymousVariable } name='_'
| name=VARIABLE
;
PNumber returns Number
: value=INT
;
PStruct returns Struct
: name=ATOM '(' arg+=PExpression0 (',' arg+=PExpression0)* ')'
| PAtom
;
PAtom returns Atom
: name=ATOM
| { AtomString } name=STRING
;
terminal fragment CHARSEQ : ('a'..'z' | 'A' .. 'Z' | '0'..'9' | '_')*;
terminal ATOM : ('a'..'z') CHARSEQ;
terminal VARIABLE : ('A'..'Z') CHARSEQ;
terminal INT returns ecore::EInt: ('0'..'9')+;
terminal STRING :
'"' ( '\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\'|'"') )* '"' |
"'" ( '\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\'|"'") )* "'"
;
terminal ML_COMMENT : '/*' -> '*/';
terminal SL_COMMENT : '//' !('\n'|'\r')* ('\r'? '\n')?;
terminal WS : (' '|'\t'|'\r'|'\n')+;
terminal ANY_OTHER: .;
When validating I'd love to search for unused variables in rules definition and suggest the user to use anonymous variable instead. Once I've understood the mechanism I may consider similar validation rules.
I know Xtext has a built-in scoping mechanism and I've been able to use it in different situations, but as you know, any IScopeProvider provides a scope for a given EReference (am I right?) and, as you can see, my grammar has no cross-references. The reason for that is simple: in Prolog a variable "definition" and its "references" are syntactically the same, so no context-free parser able to distinguish the two contexts can be generated (I'm pretty sure, even without a formal proof).
However, I think the validation algorithm is quite simple:
"while navigating the AST, collect any variable within an ad-hoc data structure and the count occurrences" or something smarter than that
Now the real question is: can I someway (re)use any part of the Xtext scoping framework, and if yes how? Or should I build a simple scoping library by my self?
Sorry for the long question and bad english, I hope I was exhaustive.
Thank you for reading.
The Xtext validation framework can reuse your scope provider instance easily, and can write validation rules. A sample for the validator is already generated for the Xtext grammar, you have to extend it with your specific validation case like follows:
public class GarbageLanguageJavaValidator extends AbstractGarbageLanguageJavaValidator {
#Inject
GarbageLanguageScopeProvider scopeProvider;
//Validation rule for theories. For any other element, change the input parameter
#Check
public void checkTheory(Theory theory) {
//here, you can simply reuse the injected scope provider
scopeProvider.getAllReferencesInTheory();
//in case of problems, report errors using the inherited error/warning methods
}
}
The created validation rules are automatically registered and executed (see also the Xtext documentation for details about validation).
I actually solved the problem a few days after I posted the question and then I was too busy to post the solution. Here it comes (for a more detailed description of both the problem and the solution, you are free to read the essay I wrote: RespectX - section 4.5 ).
I created my own IQualifiedNameProvider, called IPrologSimpleNameProvider, which simply returns the 'name' feature.
Then I created my own IContextualScopeProvider, which doesn't extend IScopeProvider. It exposes the following methods:
getContext given any AST node, it returns the root of the current context, i.e.
the EObject whose eContainer is instance of Theory and containing the
input node within its sub-tree.
getScope returns an IScope for the context of the input node.
getFilteredScope applies a type-filter to a getScope invocation (e.g. it makes
it easy to create a scope containing only Variables).
getFilteredScope filters a getScope invocation using a predicate.
Of course, the IContextualScopeProvider implementation uses an IPrologSimpleNameProvider implementation so, now, the validation rule quite simple to realize:
Given a variable, it uses the getScope method which returns an IScope containing all the variables within that context
It counts how many variables within the IScope are named after the current one
If they are lesser than 2 a warning is found.
I really hope I explained ^^"
Well, I've finally decided that I'm not crazy. So, that leaves DataMapper.
Here's what I'm doing. I have a model Msrun which has 1 Metric.
tmp = Msrun.first_or_create # I'll skip the boring details
tmp.metric = Metric.first_or_create( {msrun_id: tmp.id}, {metric_input_file: #metricsfile} )
p tmp.metric # => #<Metric #metric_input_file=nil #msrun_id=1>
tmp.metric.metric_input_file = #metricsfile
p tmp.metric # => #<Metric #metric_input_file=#<Pathname:/home/ryanmt/Dropbox/coding/rails/metrics_site/spec/tfiles/single_metric.txt> #msrun_id=1>
So, why doesn't this work? I'm reading http://datamapper.org/docs/create_and_destroy and doing what it shows working. This has been terribly arduous. Thanks for any help.
Update:
I still can't figure out what is going on, but to prove I'm not insane...
puts Metric.all # => []
tmp.metric = Metric.first_or_create( {msrun_id: tmp.id}, {metric_input_file: #metricsfile} )
puts Metric.all # => [] #??????????????
tmp.metric.metric_input_file = #metricsfile
p tmp.metric # => #<Metric #metric_input_file=#<Pathname:/home/ryanmt/Dropbox/coding/rails/metrics_site/spec/tfiles/single_metric.txt> #msrun_id=1>
tmp.metric.save
puts Metric.all # => [#<Metric #metric_input_file=#<Pathname:/home/ryanmt/Dropbox/coding/rails/metrics_site/spec/tfiles/single_metric.txt> #msrun_id=1>]
So, not only is first_or_create not delivering on the behavior I expect by reading the source
def first_or_create(conditions = {}, attributes = {})
first(conditions) || create(conditions.merge(attributes))
end
but it is also not even creating.
I'm probably missing something here (more of those boring details might help) but if the metric exists, it's metric_input_file shouldn't be updated, i.e., it's only set when new. If you're after updating then you can do
.first_or_create(msrun_id: tmp.id).update(metric_input_file: #metricsfile)
Or if not hitting the database twice is relevant, then
m = Metric.first_or_new(msrun_id: tmp.id)
[set..save..assign]
But if it's not being set on new models, I don't see what would cause that from the code posted so far, more..?
[UPDATED]
Based on your new code, I'd say this is "a classic case" of a false DM save. I usually add the following line to an initialization section, e.g., application.rb in Rails.
DataMapper::Model.raise_on_save_failure = true
Unfortunately, the exception raised never tells you why (there's a special place in hell for that choice, right next to people who talk in theaters.) But it's typically one of:
a slightly incorrect association definition
a has/belongs_to that isn't "required: false" and isn't set
putting the wrong datatype into a field, e.g., a string into a decimal
a validation failing
If you want to post your model definitions, the problem may be spottable there.
In addition to the answer above, I've seen this call die (like, literally halt all execution) with no error when I was doing a find_or_create that would have created an object that violated the primary key constraint. This is because the datamapper model was not in sync with the actual database schema.