Let's say I have an abstract class which has a non-abstract instance method for children to inherit:
# - abstract.cr
abstract class Abstract
def foo
2
end
end
How do I write a spec for this?
# - abstract_spec.cr
it "returns 2 from #foo" do
Abstract.instance.foo.should eq 2 #???
end
There might be a better way to this (hence my posting the question, I'd love to get feedback from the community), but one way I can think to do this is to have a class inherit from the parent in the test. That way you are abstractly focusing on "any" implementation of the class.
# - abstract_spec.cr
class AbstractTest < Abstract
end
it "returns 2 from #foo" do
AbstractTest.new.foo.should eq 2
end
Related
I want to define a generic memoizing wrapper in Crystal.
I have the following crystal code:
module Scalar(T)
abstract def value: T
end
class ScSticky(T)
include Scalar(T)
def initialize(sc : Scalar(T))
#sc = sc
#val = uninitialized T
end
def value: T
#val ||= #sc.value
end
end
In other words I want ScSticky to call the underlying Scalar(T) only once and return the cached output for all subsequent calls.
However, the above approach doesn't work if T is Int32
For instance, when wrapping this class
class ScCounter
include Scalar(Int32)
def initialize
#val = 100
end
def value: Int32
#val += 1
#val
end
end
ScSticky(ScCounter.new).value will always be equal to 0 (as I understand it, because the unitialized Int32 is actually initialized with 0 value)
I would highly appreciate some help with this problem
Upd: It seems that the proper way to implement this is using nil , however I have problems with understanding how exactly such implementation should look. I also want to be able to memoize .value method even if it returns nil (In other words, if the T is a nilable type)
You are using an unsafe feature "uninitialized", which means, "keep whatever was there in memory previously" (in theory the value is random and possibly invalid, in practice you often end up with 0 anyway -- but it's still not guaranteed at all).
The short story about the uninitialized feature is please never use it.
This behavior wouldn't surprise you if you wrote #val = 0 -- and that's kinda what you wrote.
You must define #val : T? = nil -- to make it nilable (have this separate possible value of nil, which is its own type - Nil).
You may have thought that unitialized brings nil into the picture, but it definitely doesn't.
In response to your comment about also including nil into possible values, here's a full solution, which, instead of Nil, uses a unique "sentinel" struct, that the user can never create.
module Scalar(T)
abstract def value: T
end
private struct Sentinel
end
class ScSticky(T)
include Scalar(T)
#val : T | Sentinel = Sentinel.new
def initialize(#sc : Scalar(T))
end
def value: T
val = #val
if val.is_a?(Sentinel)
#val = #sc.value
else
val
end
end
end
class ScCounter
include Scalar(Int32)
def initialize
#val = 100
end
def value: Int32
#val += 1
end
end
sc = ScSticky.new(ScCounter.new)
p! sc.value #=> 101
p! sc.value #=> 101
I need do a advanced query,
My classes
class P:
class R:
p = fk(P)
class S:
R = fk(R)
I need some like this, from R class:
S.objects.filter(r.p = self.p)
In other words, all S where P is equal to a given P
I am not Pro with QuerySets
Thanks
Assuming you have a instance of the p class in self.p then the queryset
S.objects.filter(r__p=self.p) would work. Next time put a bit more effort into your question though or people won't want to put effort into an answer.
I have the following model which is populated with something like this:
Property
concept_id name value
1 definition blablabla
1 prefLabel prefferedLabel
1 scope Scopeee
1 NOT_NEEDED a not needed value
2 definition another definition
2 prefLabel another label
2 scope another scope
.........................
I want to obtain this result in query(under the form of a list, dictionary, queryset, it doesn't matter which form):
concept_id definition prefLabel scope
1 blablabla prefferedLabel Scopeee
2 another definition another label another scope
How can I achieve this? Thanks
EDIT: I am using MySQL.
My ugly solution is this one
for concept_id in Concept.objects.all().values_list('id', flat=True):
Property.objects.filter(concept_id=concept_id, name__in=['prefLabel', 'scope', 'definition'])
.....
But is realy ugly, I want something different
THE SOLUTIONS OF pcoronel:
table = []
for concept in Concept.objects.all():
row = {'code': concept.id}
result=concept.property_set.filter(
name__in=['prefLabel', 'scope', 'definition'],
)
for r in result:
row.update({
r.name: r.value,
})
table.append(row)
Not sure if this is the best solution
Assuming your Property model has a field: models.ForeignKey('Concept', ...), you can simply follow that relationship backwards:
# iterate through Concepts and get desired related Properties using their name
for concept in Concept.objects.all():
concept.property_set.filter(name__in=['prefLabel', 'scope', 'definition'])
I do a little project in Pascal and I have a problem.
I have 3 class (1 parent 2 child)
TGroup = class
...
end;
TUser = class(TGroup)
...
public
someVariableForUser: Integer;
...
end;
TAdmin = class(TGroup)
...
public
someVariableForAdmin: Integer;
...
end;
//And main program like this:
var
Person: TGroup;
begin
Person := TGroup.Create();
Person.someVariableForAdmin := 1;
And i get Error: identifier idents no member "someVariableForAdmin"
When I change var Person: TAdmin, so everything works fine.
Please help, Thanks alot.
This is exactly what should be expected. A TGroup instance has no knowledge of types that descend from it, or any fields or methods those descendants might declare. If you want to access something that's contained in TAdmin and it's descendents, you need to create an instance of TAdmin or one of it's descendents.
If you want to access something in a TAdmin, you have to create a TAdmin in the first place:
var
Person: TGroup;
begin
Person := TAdmin.Create;
(Person as TAdmin).someVariableForAdmin := 1;
end.
It's not clear from your question what exactly you're trying to accomplish. You might want to post another question explaining your desired goal, post some base code, and ask for help in changing it to reach that goal. (It's too late to edit this one for that, as that would change the entire meaning of the question after you've received multiple answers to it.)
I have an uniform list of objects in python:
class myClass(object):
def __init__(self, attr):
self.attr = attr
self.other = None
objs = [myClass (i) for i in range(10)]
Now I want to extract a list with some attribute of that class (let's say attr), in order to pass it so some function (for plotting that data for example)
What is the pythonic way of doing it,
attr=[o.attr for o in objsm]
?
Maybe derive list and add a method to it, so I can use some idiom like
objs.getattribute("attr")
?
attrs = [o.attr for o in objs] was the right code for making a list like the one you describe. Don't try to subclass list for this. Is there something you did not like about that snippet?
You can also write:
attr=(o.attr for o in objsm)
This way you get a generator that conserves memory. For more benefits look at Generator Expressions.