Let say I have 3 models: A, B and C with the following relations.
A can have many B and many C.
B can have many C
Is the following correct:
class A(models.Model):
...
class B(models.Model):
...
a = models.ForeignKey(A)
class C(models.Model):
...
a = models.ForeignKey(A)
b = models.ForeignKey(B)
Or is there a more efficient way of doing this ?
In short, yes. It's all correct, I have nothing to say. (On a side note, shouldn't that be models.ForeignKey(model_name) ?)
Related
I've got two new-style MATLAB classes - B & C, both concrete subclasses of an abstract parent, A. A is a subclass of hgsetset (handle class). I'd like to put them in an array in MATLAB, and treat them both as As. They are defined, roughly, as:
classdef A <hgsetget
methods
function foo(this)
%does some common stuff, then
this.fooWorker;
end
end %public Methods
methods(Abstract, Access=protected)
fooWorker(this);
end %abstract Methods;
end
classdef B < A
methods(Access=protected)
function fooWorker(this)
%implementation
end
end %protected Methods;
end
However if I do this:
arr = [b c]; % where b & c are objects of type B & C respectively.
arr(1).foo;
arr(2).foo;
MATLAB will tell me both are of type B, and if I call the abstract method from A that both implement (foo), it executes, essentially, two copies of b.
However, if I reverse the order:
arr = [c b];
It tells me that both are of type C, and if I try to execute foo on both, it executes, essentially two copies of c.
Any ideas how to use subclasses in a polymorphic way?
I know that I can put them in a cell array and get 90% of what I need. But that is a bit of a kludge.
You can do this now in R2011a by subclassing matlab.mixin.Heterogeneous. So for example as in your code the abstract class would be:
classdef A < matlab.mixin.Heterogeneous
methods
function foo(this)
disp('In abstract parent');
this.fooWorker;
end
end
methods(Abstract, Access=protected)
fooWorker(this);
end
end
and the subclasses would look like:
classdef B < A
methods(Access=protected)
function fooWorker(this)
disp('In B');
end
end
end
and similarly for a class 'C'. This then gives the following output from MATLAB:
>> b = B;
>> c = C;
>> arr = [b, c];
>> arr(1).foo
In abstract parent
In B
>> arr(2).foo
In abstract parent
In C
>>
Unfortunately, all the elements of an array in MATLAB must be of the same type. When you concatenate different classes, MATLAB will attempt to convert them all to the same class.
If you've defined one of your classes as being inferior or superior to the other (using the InferiorClasses attribute or the INFERIORTO/SUPERIORTO functions), then the methods of the more superior class are invoked. If you haven't specified a relationship between the classes, then the two objects have equal precedence and MATLAB calls the left-most object method. This is likely why arr = [b c]; creates an array of class B and arr = [c b]; creates an array of class C.
Option 1: Cell arrays
If you want to execute the foo method defined for class B on object b, and also execute the foo method defined for class C on object c, then you will likely have to use cell arrays and the function CELLFUN. If foo doesn't return a value, you could do something like this:
arr = {b,c};
cellfun(#foo,arr); % Invoke foo on each element of the cell array
Option 2: Fun with jury-rigging polymorphic behavior
For fun, I came up with a potential solution which technically works, but has some limitations. To illustrate the idea, I've put together a few sample classes similar to what you listed in the question. Here's the abstract superclass classA:
classdef classA < hgsetget
properties
stuff
end
properties (Access = protected)
originalClass
end
methods
function foo(this)
disp('I am type A!');
if ~strcmp(class(this),this.originalClass)
this = feval(this.originalClass,this);
end
this.fooWorker;
end
end
methods (Abstract, Access = protected)
fooWorker(this);
end
end
And here's an example of the subclass classB (classC is exactly the same with everywhere B replaced by C and vice versa):
classdef classB < classA
methods
function this = classB(obj)
switch class(obj)
case 'classB' % An object of classB was passed in
this = obj;
case 'classC' % Convert input from classC to classB
this.stuff = obj.stuff;
this.originalClass = obj.originalClass;
otherwise % Create a new object
this.stuff = obj;
this.originalClass = 'classB';
end
end
end
methods (Access = protected)
function fooWorker(this)
disp('...and type B!');
end
end
end
The constructors for classB and classC are designed such that the two classes can be converted to one another. The property originalClass is initialized at creation and indicates what the original class of the object was. This property will remain unchanged if an object is converted from one class to another.
Within the foo method, the current class of the object passed in is checked against its original class. If they differ, the object is first converted back to its original class before invoking the fooWorker method. Here's a test:
>> b = classB('hello'); % Create an instance of classB
>> c = classC([1 2 3]); % Create an instance of classC
>> b.foo % Invoke foo on b
I am type A!
...and type B!
>> c.foo % Invoke foo on c
I am type A!
...and type C!
>> arr = [b c] % Concatenate b and c, converting both to classB
arr =
1x2 classB handle
Properties:
stuff
Methods, Events, Superclasses
>> arr(1).foo % Invoke foo on element 1 (formerly b)
I am type A!
...and type B!
>> arr(2).foo % Invoke foo on element 2 (formerly c)
I am type A!
...and type C!
One key limitation (aside from being a little ugly) is the case where classB and classC each have properties that the other does not. In such a case, converting to the other class and then converting back would likely cause those properties to be lost (i.e. reset to their default values). However, if one class were a subclass of the other, such that it had all the same properties and thensome, there is a solution. You could set the subclass to be superior to the superclass (see discussion above) such that concatenating objects of the two classes will always cause the superclass objects to be converted to the subclass. When converted back within "polymorphic" methods (like foo above), no object data will be lost.
I don't know how workable a solution this is, but maybe it will at least give you some interesting ideas. ;)
I have four classes: A, B, C and S. Class A has inferred instances i1 and i2 which are based on a numerial value condition (in Equivalent To). Class B has inferred instances i3 and i4 which are based on a numerial value condition (in Equivalent To). A and B are subclasses of S.
Each instance has an xsd:dateTime value.
I would like to model that each instance from A and B which have an equal xsd:dateTime value are also instances (inferred) from class C. How do I model such an expression with Protege?
Thanks in advance.
You will have to use SWRL for that. In the SWRL tab of Protege add the following rule:
A(?a) ^ B(?b) ^ hasDateTime(?a, ?aDateTime) ^ hasDateTime(?b, ?bDateTime) ^
swrlb:equal(?aDateTime, ?bDateTime) -> C(?a) ^ C(?b)
assuming you have a hasDateTime data property.
I have performed a "group by" on a relation and the result is similar to the following:
g1,{a1,a2,a3}
g2,{b1,b2,b3,b4}
g3,{c1,c2,c3,c4,c5,c6}
...
so the first field is the group and the second filed is a bag of tuples where each bag may have different number of elements. What I want to do is to generate a new relation which includes all the elements in the second fields. Therefore, the output will be:
B={a1,a2,a3,b1,b2,b3,b4,c1,c2,c3,c4,c5,c6}
Coud you help on this?
Sara
If you want what I think you want you are seeking to create a new relation where each of the tuples that was formerly in the bags from grouping is now an entire record. To do this, use the FLATTEN operator, which blows up the bag into multiple records. If you can assume that all of the tuples in the bags have the same schema, you can additionally FLATTEN those to promote the tuple elements to full-fledged fields:
If A is the result of the grouping, and
DESCRIBE A;
{(key:chararray, bag:{})}
You can do
B = FOREACH A GENERATE FLATTEN(bag) AS tuple;
Then to convert the tuples into full rows, do
C = FOREACH B GENERATE FLATTEN(tuple);
You can read more about FLATTEN here.
In order to get to a result like what you started with, I did:
grunt> A = LOAD '../../../input/tuplesSample.txt' using PigStorage(' ') AS (grupo:chararray, charo:chararray);
grunt> DESCRIBE A;
A: {grupo: chararray,charo: chararray}
grunt> B = GROUP A by grupo;
grunt> DESCRIBE B;
B: {group: chararray,A: {(grupo: chararray,charo: chararray)}}
grunt> C = FOREACH B GENERATE $0 as grupo, $1.charo as charos;
grunt> DESCRIBE C;
C: {grupo: chararray,charos: {(charo: chararray)}}
grunt> DUMP C;
C: {grupo: chararray,charos: {(charo: chararray)}}
(g1,{(a1),(a2),(a3)})
(g2,{(b4),(b3),(b2),(b1)})
(g3,{(c4),(c5),(c6),(c2),(c1),(c3)})
Then I did this, to give you the new relation (E below) that contains all the elements in a single bag.
grunt> D = FOREACH C GENERATE FLATTEN($1) as charos;
grunt> DESCRIBE D;
D: {charos: chararray}
grunt> E = GROUP D ALL;
grunt> DESCRIBE E;
E: {group: chararray,D: {(charos: chararray)}}
grunt> DUMP E;
(all,{(c3),(c1),(c2),(c6),(c5),(c4),(b1),(b2),(b3),(b4),(a3),(a2),(a1)})
Suppose R = {A,B,C,D}
And FD = C→D,C→A,B→C
I am supposed to find:
1. the key(s)
2. the NF it is in
3. the BCNF (if possible and if not in already)
So here's what I've got so far:
the key is B since it transitively determines C which determines D and A.
it is in 2NF since dependancies are on the whole key
R1 = {B,C} R2 = {C, A, D}
So here's where I have an issue. The mark scheme says to decompose R into AC, BC, and CD. But why wouldn't my answer be right? Am I saying the FD is C -> {A,D} and if so is this difference to C -> A and C -> D?
When you're asked to compute the minimum cover of R, you're usually expected to answer like this.
C -> D
C -> A
B -> C
When you're asked to elevate R to BCNF, you're usually expected to answer like this.
B C
C AD
If you're not using a standard textbook, I can't give you any suggestions. Questions and answers written by TAs (teaching assistants) are particularly hard to understand. Sometimes they're just wrong.
I want to simplify the following code in C. Is there any hash table in C to make it simple? For example "dict" in Python.
int a, b, c, d ......
a = get_value_from_sth( A_NAME )
b = get_value_from_sth( B_NAME )
c = get_value_from_sth( C_NAME )
d = get_value_from_sth( D_NAME )
......
No, C does not have a built-in hash table type like Python's dicts. You may be able to get by with an array, depending on your needs.
Check out glib hash tables. Not "official" or "built in," but widely used and as close as you can get to a standard hash table implementation for C.
You will need to create a function to map a ptr to a value in an array.
This is how python does it.
http://docs.python.org/c-api/dict.html
Personally I do not bother. It's C. The best solution will still be ugly.