I'm struggling to make a flexible data structure (like a relational database) for a quiz in ActionScript 3.0.
I have a number of questions, each with 2 alternatives:
Questions
| id | alt1 | alt2 | correctAlt |
---------------------------------------
| 0 | Sweden | Denmark | 1 |
| 1 | Norway | Finland | 2 |
| 2 | Iceland | Ireland | 1 |
And a number of users with unique IDs:
Users
| id | age | sex | profession | totalCorrect |
-------------------------------------------------
| A5 | 25 | 0 | "Lorem" | 0 |
| A6 | 45 | 1 | "Ipsum" | 0 |
| A7 | 32 | 1 | "Dolor" | 0 |
And each user might answer a question:
Answers
| question_id | user_id | answer |
----------------------------------
| 0 | A5 | 1 |
| 1 | A6 | 2 |
| 2 | A7 | 1 |
How can I represent this in AS3?
And how can I, when I've collected all the data, answer questions such as:
a. How many users answered question 1?
b. How many % of the users answering question 1 were correct?
c. And how can I sum the number of correct answers for each user and update the totalCorrect column?
Whether you use a database or not, it's still possible to represent this data with objects. You can create specific classes.
Here's a basic example for a Question class.
public class Question
{
private var _id:int;
private var _alternatives:Array;
private var _correctAnswer:int;
public function Question()
{
}
//----------- Group: Getters & Setters
// follow the same principle as alternatives for id & correctAnswer
public function set alternatives(value:Array):void
{
_alternatives = value;
}
public function get alternatives():Array
{
return _alternatives;
}
// etc.....
}
var question1:Question = new Question();
question1.alternatives = ["Sweden" , "Denmark"]
question.correctAnswer = 1;
question.id = 0;
It's also possible to pass parameters to the constructor
public class Question
{
private var _id:int;
private var _alternatives:Array;
private var _correctAnswer:int;
public function Question(id:int , alt:Array, correct:int)
{
_id = id;
_alternatives = alt;
_correctAnswer = correct;
}
var question1:Question = new Question(0 , ["Sweden" , "Denmark"] , 1);
Do something similar for the Users , then create another class where you'll manipulate the data.
Try and find some resources about Classes in general and Object Oriented Programming in particular.
I suggest you to store this data in a SQL database.
A SQL database will help you to extract data by your questions.
If you are using Air, this should be easy as Air supports SQLite, a local database.
If you are developing a .swf file, you can connect to a SQL database using AMF or using POST or GET methods to a server who will fetch the data by the SQL request sended using the URLRequest() method.
I strongly recommend to use a SQL database as this is made for your type of questions.
Here's your questions translated to SQL
How many users answered question 1?
You forgot to add id to your answers table
SELECT users.id FROM users, answers, questions WHERE questions.id = 0 AND answers.question_id = questions.id AND answers.answer = questions.correctAlt;
How many users answered question 1?
This can be done in two queries. Both will return a number of users. First, all users who answered the question. Secondly, the same as the first question translated.
SELECT users.id FROM users, answers, questions WHERE questions.id = 0 AND answers.question_id = questions.id;
SELECT users.id FROM users, answers, questions WHERE questions.id = 0 AND answers.question_id = questions.id AND answers.answer = questions.correctAlt;
How can I sum the number of correct answers for each user and update the totalCorrect column?
You don't even need this sort of column in your table as it can be resolved by a simple query.
SELECT answers.id FROM users, answers, questions WHERE answers.question_id = questions.id;
I took the time to look into your problem in more detail. I created three classes as models for the Question, User & Answer and an AnswerEvent class.
The main class serves as a central point to manipulate data. When a user answers a question , the user's answer(Answer class ) dispatches an event to inform the main class. The answer has a user property , a question property and a isCorrect property, the AnswerEvent contains an Answer object that can be stored in the main class.
After the event has been dispatched , the answer is stored in an array of answers. Since each answer contains the user data as well as the question answered & how it was answered , you can use this array to answer your a, b & c questions.
As for the classes, I followed a similar principle to that exposed in my first reply. I don't think there's enough space here to post all the code so I just posted some excerpts.
//Inside the main class
private var answers:Array = [];
private function init():void
{
this.addEventListener(AnswerEvent.ANSWER , answerEventListener );
var q1:Question = new Question( 0 , ["Sweden" , "Denmark"] , 0 );
var q2:Question = new Question( 1 , ["Norway" , "Finland"] , 1 );
var q3:Question = new Question( 2 , ["Iceland" , "Ireland"] , 0 );
var user1:User = new User( 5 , 25 , 0 , "Lorem" );
var user2:User = new User( 6 , 45 , 1 , "Ipsum" );
var user3:User = new User( 7 , 32 , 1 , "Dolor" );
//if the answer is correct , the totalCorrect property is incremented
// in the User class, check the Answer class below for an explanation of the
//parameters
user1.answer( new Answer( this , user1 , q1 , 1 ));
}
private function answerEventListener(event:AnswerEvent):void
{
answers.push(event.answer);
trace( this , event.answer.isCorrect );
trace( this , event.answer.user.age );
}
Here's a model for the Answer class, I didn't add the getters for lack of space. The AnswerEvent extends the Event class and add an answer property of type Answer
public class Answer
{
private var _question:Question;
private var _answer:int;
private var _user:User;
private var _isCorrect:Boolean;
public function Answer(dispatcher:EventDispatcher , user:User , question:Question , answer:int)
{
this._user = user;
this._question = question;
this._answer = answer;
// not essential but will help iterate thru correct answers
// the _answer property should be _answerIndex really, in order not to be confused
// with an Answer object ( quick job ! )
if( question.correctAnswer == answer )
_isCorrect = true;
// the this keyword corresponds to this answer
dispatcher.dispatchEvent( new AnswerEvent(AnswerEvent.ANSWER , this) );
}
}
Related
I have models like below
class Scheduler(models.Model):
id = <this is primary key>
last_run = <referencing to id in RunLogs below>
class RunLogs(models.Model):
id = <primary key>
scheduler = <referencing to id in Scheduler above>
overall_status = <String>
Only when the scheduler reaches the scheduled time of the job, RunLogs entry is created.
Now I am querying on RunLogs to show running schedules as below.
current = RunLog.objects\
.filter(Q(overall_status__in = ("RUNNING", "ON-HOLD", "QUEUED") |
Q(scheduler__last_run__isnull = True))
The above query gives me all records with matching status from RunLogs but does not give me records from Scheduler with last_run is null.
I understand why the query is behaving so but is there a way to get records from scheduler also with last_run is null
?
I just did the same steps which you followed and found the reason why you where getting all the records after running your query. Here is the exact steps and a solution for this.
Steps
Created models
from django.db import models
class ResourceLog(models.Model):
id = models.BigIntegerField(primary_key=True)
resource_mgmt = models.ForeignKey('ResourceMgmt', on_delete=models.DO_NOTHING,
related_name='cpe_log_resource_mgmt')
overall_status = models.CharField(max_length=8, blank=True, null=True)
class ResourceMgmt(models.Model):
id = models.BigIntegerField(primary_key=True)
last_run = models.ForeignKey(ResourceLog, on_delete=models.DO_NOTHING, blank=True, null=True)
Added the data as following:
resource_log
+----+----------------+------------------+
| id | overall_status | resource_mgmt_id |
+----+----------------+------------------+
| 1 | RUNNING | 1 |
| 2 | QUEUED | 1 |
| 3 | QUEUED | 1 |
+----+----------------+------------------+
resource_mgmt
+----+-------------+
| id | last_run_id |
+----+-------------+
| 1 | NULL |
| 2 | NULL |
| 3 | NULL |
| 4 | 3 |
+----+-------------+
According to the above table resource_mgmt(4) is referring to resource_log(3). But thing to be noted is, resource_log(3) is not referring to resource_mgmt(4).
Ran the following command in python shell
In [1]: resource_log1 = ResourceLog.objects.get(id=1)
In [2]: resource_log.resource_mgmt
Out[2]: <ResourceMgmt: ResourceMgmt object (1)>
In [3]: resource_log1 = ResourceLog.objects.get(id=2)
In [4]: resource_log.resource_mgmt
Out[4]: <ResourceMgmt: ResourceMgmt object (1)
In [5]: resource_log1 = ResourceLog.objects.get(id=3)
In [6]: resource_log.resource_mgmt
Out[6]: <ResourceMgmt: ResourceMgmt object (1)>
from this we can understand that all the resource_log objects are referring to 1st object of resource_mgmt(ie, id=1).
Q) Why all the objects are referring to 1st object in the resource_mgmt?
resource_mgmt is a foreign key field which is not null. Its default value is 1. when you create a resource_log object, if you are not specifying resource_mgmt, it will add the default value there which is 1.
Run your query
In [60]: ResourceLog.objects.filter(resource_mgmt__last_run__isnull = True)
Out[60]: <QuerySet [<ResourceLog: ResourceLog object (1)>, <ResourceLog: ResourceLog object (2)>, <ResourceLog: ResourceLog object (3)>]>
This query is returning all three ResourceLog objects because all three are referring to 1st resource_mgmt object which has its is_null value as True
Solution
You actually want to check the reverse relationship.
We can achieve this using two queries:
rm_ids = ResourceMgmt.objects.exclude(last_run=None).values_list('last_run', flat=True)
current = ResourceLog.objects.filter(overall_status__in = ("RUNNING", "QUEUED")).exclude(id__in=rm)
The output is:
<QuerySet [<ResourceLog: ResourceLog object (1)>, <ResourceLog: ResourceLog object (2)>]>
Hope that helps!
I have an issue and i'm looping on it! :| I hope someone can help me..
So i have an input file (.xls), that is simple but there are a row (lets say its "ROW1") that is like this:
ROW1 | ROW2 | ROW3 | ROW_N
765 | 1 | AAAA-MM-DD | ...
null | 1 | AAAA-MM-DD | ...
null | 1 | AAAA-MM-DD | ...
944 | 2 | AAAA-MM-DD | ...
null | 2 | AAAA-MM-DD | ...
088 | 7 | AAAA-MM-DD | ...
555 | 2 | AAAA-MM-DD | ...
null | 2 | AAAA-MM-DD | ...
There are no stardard here, like you can see.. There are some lines null (ROW1) and in ROW2, there are equal numbers, with different association to ROW1 (like in line 5 and 6, then in line 8 and 9).
My objective is to copy and paste the values from ROW1, in the ROW1 after when is null, till isn't null. Basically is to copy form previous step, when is null...
I'm trying to use the "Formula" step, by using something like:
=IF(AND(ISBLANK([ROW1]);NOT(ISBLANK([ROW2]));ROW_n=ROW1;IF(AND(NOT(ISBLANK([ROW1]));NOT(ISBLANK([ROW2]));ROW_n=ROW1;ROW_n=""));
But nothing yet..
I've tried "Analytic Query" but nothing too..
I'm using just stream a xls file input..
Tks very much, any help is very much appreciiated!!
Best Regardsd!
Well i discover a solution, adding a "User Defined Java Class" with the code below:
import java.util.HashMap;
private FieldHelper output_field, card_field;
private RowSet out, log;
private String previou_card =null;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
if (first)
{
first = false;
out = findTargetRowSet("out");
output_field = get(Fields.Out, "previous_card");
} else {
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
r = createOutputRow(r, data.outputRowMeta.size());
if (previous_card != null) {
output_field.setValue(r, previous_card);
}
if (card_field == null) {
card_field = get(Fields.In, "Grupo de Cartões");
}
String card = card_field.getString(r);
if (card != null && !card.isEmpty()) {
previous_card = card;
}
// Send the row on to the next step.
putRowTo(data.outputRowMeta, r, out);
}
return true;
After this i have to put a few steps but this help very much.
Thank you mates!!
Finally i got result. Please follow below steps
Below image is full transformation screen.
Data Grid Data will be like these. Sorry for that in my local i don't have Microsoft because of that i took Data Grid. Instead of Data Grid you can drag and drop Microsoft Excel Input step.
Drag and Drop one java script step and write below code.
Last step of transformation, drag and drop Select values step and select the columns.( These step is no necessary)
Final result will be like these.
Hope this helps.
I am creating a document from a Template, and cannot figure out how to insert a table at the right position.
I have the table in memory as a 2D array, and in the template I have place-holders like this (including the square-brackets):
...
[TABLE 1]
...
[TABLE 2]
...
[TABLE 3]
...
Each of these placeholders is in a 1x1 table.
I have managed to insert my first array in the right position, but when I then search for the following placeholders my array always gets inserted after Table 1.
My code is the following (I found this online and adapted it slightly):
function insertTable(targetdoc, stringToReplace, tableValues) {
var body = targetdoc.getBody();
var searchElement = targetdoc.getActiveSection();
var searchType = DocumentApp.ElementType.TABLE;
var searchHeading = DocumentApp.ElementType.TABLE_CELL;
var searchResult = null;
// Search until the table is found.
while (searchResult = searchElement.findElement(searchType, searchResult)) {
var par = searchResult.getElement().asTable();
var tabletext = par.getText();
var substr=tabletext.search(stringToReplace);
if (substr >0 ) {
var childindex = body.getChildIndex(par);
var oTable = body.insertTable(childindex+1, tableValues);
return oTable;
}
}
}
and the calling code is:
var oTable = insertTable(oOutputFile,"["+cFieldID+"]",aTable);
where oOutputfile is the new doc, cFieldID is the placeholder text, and aTable is the 2D array.
Can anyone help me get this to work, so that it inserts each array into the correct position?
Thanks
I have written something very similar that might prove useful to you, see GAS Template Engine
It will accept any JSON string and replace place holders in a document that match the structure of the JSON. When an array is encountered, the script looks for a place holder in a table and it will create table rows for each element of the array.
So if your JSON string contains an array as below :
var json = { myarr : [ { col1: "a", col2 : "b" }, { col1 : "c", col2 : "d" }] }
then the script will look for a table in the template document that looks like this :
------------------------------------------------------
| $myarr.col1 | $myarr.col2 |
-------------------------------------------------------
and transform that into :
-----------------------------------
| a | b |
-----------------------------------
| c | d |
-----------------------------------
it will keep the formatting of the rows as well.
It is just a proof of concept for a templating engine but it should be enough to solve your problem.
Thanks koma for your solution which I will certainly use in future, however it was a bit of overkill for what I was looking for.
Finally, I found the solution to what I needed after a mammoth debugging session, and my function shown above has now become:
function insertTable(targetdoc, stringToReplace, tableValues) {
var oDoc = targetdoc.getBody(); // Document
var oSR = oDoc.findText(stringToReplace); // SearchResult
var oPara = oSR.getElement().asText().getParent(); // Paragraph
var nIndex = oDoc.getChildIndex(oPara); // Index
var oTable = oDoc.insertTable(nIndex, tableValues); // Table
return oTable;
}
so, for example, if I have a doc (oDoc) with the following placeholder
[TABLE 1]
an array
aData: {{"","column 1","column 2"},{"row 1","data 11","data 12"},{"row 2","data 21","data 22"}}
and a variable
cFieldID = "TABLE 1";
and call my function
oTable = insertTable(oDoc, cFieldID, aData);
oOutputFile.replaceText("\\["+cFieldID+"\\]","");
I obtain the following in lieu of the placeholder text
-----------------------------------
| | column 1 | column 2 |
-----------------------------------
| row 1 | data 11 | data 12 |
-----------------------------------
| row 2 | data 21 | data 22 |
-----------------------------------
This is less generic and powerful than koma's solution, but sufficient for what I need for now.
Chris
i have in my DB table TBus fields like s1,s2.s3.s4,...sn
i get the seatNumber as a parameter and want to get that field just like i have it in my code.
Any idea please.
private string checkSeatValue(int busTripId, int seatNumber)
{
string sNumber = "s" + seatNumber.ToString();
// Some code here
string sqlCommand = "SELECT " + sNumber + " FROM TBus WHERE Id=" + busTripId + "";
// More code here
}
If you want pure Linq2SQL code, you should get the TBus object:
var bus = yourDataContext.GetTable<TBus>().Where(bus => bus.BusTripId == busTripId).SingleOrDefault();
And then switch your seat variable to get the desired field:
var seat;
switch(seatNumber)
{
case "s1":
seat = bus.Seat1;
break;
case "s2":
seat = bus.Seat2;
break;
// And so it goes on...
}
However, you can do pure SQL code via Linq also or play with reflection.
-- EDIT
As I said in the comment, I believe your database model can be improved. My advice would be having two tables:
TBus Table
TBusId - int [PK]
...
TBusSeat Table
TBusSeatId - int [PK]
TBusIs - int [FK referencing TBus.TBusId]
SeatNumber - int
...
That way, you have more natural flexibility to deal with those king of situations. Consider the following set of data:
TBus Table
TBusId
------
1
2
TBusSeat Table
TBusSeatId | TBusId | SeatNumber | PassengerName
------------------------------------------------
1 1 1 Josh Doe
2 1 2 John Doe
3 1 3 Jane Doe
4 2 1 Jack Doe
So, to deal with your desired query with Linq2SQL, it would be simple as this:
var seat = yourDataContext.GetTable<TBusSeat>().Where(seat => seat.TBusId == 1 && seat.SeatNumber == 2).SingleOrDefault();
And calling seat.PassengerName would result in John Doe.
create table test(
container varchar(1),
contained varchar(1)
);
insert into test values('X','A');
insert into test values('X','B');
insert into test values('X','C');
insert into test values('Y','D');
insert into test values('Y','E');
insert into test values('Y','F');
insert into test values('A','P');
insert into test values('P','Q');
insert into test values('Q','R');
insert into test values('R','Y');
insert into test values('Y','X');
select * from test;
mysql> select * from test;
+-----------+-----------+
| container | contained |
+-----------+-----------+
| X | A |
| X | B |
| X | C |
| Y | D |
| Y | E |
| Y | F |
| A | P |
| P | Q |
| Q | R |
| R | Y |
| Y | X |
+-----------+-----------+
11 rows in set (0.00 sec)
Can I find out all the distinct values contained under 'X' using a single self join?
EDIT
Like, Here
X contains A, B and C
A contains P
P contains Q
Q contains R
R contains Y
Y contains C, D and E...
So I want to display A,B,C,D,E,P,Q,R,Y when I query for X.
EDIT
Got it right by programming.
package com.catgen.helper;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.catgen.factories.Nm2NmFactory;
public class Nm2NmHelper {
private List<String> fetched;
private List<String> fresh;
public List<String> findAllContainedNMByMarketId(Connection conn, String marketId) throws SQLException{
fetched = new ArrayList<String>();
fresh = new ArrayList<String>();
fresh.add(marketId.toLowerCase());
while(fresh.size()>0){
fetched.add(fresh.get(0).toLowerCase());
fresh.remove(0);
List<String> tempList = Nm2NmFactory.getContainedNmByContainerNm(conn, fetched.get(fetched.size()-1));
if(tempList!=null){
for(int i=0;i<tempList.size();i++){
String current = tempList.get(i).toLowerCase();
if(!fetched.contains(current) && !fresh.contains(current)){
fresh.add(current);
}
}
}
}
return fetched;
}
}
Not the same table and fields though. But I hope you get the concept.
Thanks guys.
You can't get all the contained objects recursively using a single join with that data structure. You would need a recursive query but MySQL doesn't yet support that.
You could however construct a closure table, then you can do it with a simple query. See Bill Karwin's slideshow Models for heirarchical data for more details and other approaches (for example, nested sets). Slide 69 compares the different designs for ease of implementing 'Query subtree'. Your chosen design (adjacency list) is the most awkward of all four designs for this type of query.
What about reading the whole table into a php array, and determine the children via. a function which would call itself?
But this is not a good solution if the table has more than 10000 rows...