why are variables not showing up as members of objects? - javascript

hey guys i'm working on some code for a class project and for some reason the demo code i got in class is not working the same way. the errors aren't making any since can i get some help debugging i know its probably retarded. thanks a lot in advance.
function BuildGrid()
{
//begin with a BeginVertical() call so that controls
//are stacked vertically
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
//begin loopping for the rows
for(var i=0; i<rows; i++)
{
//call BeginHorizontal() so that controls are stacked
//horizontally
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
//begin looping for the columns
for(var j=0; j<cols; j++)
{
//getting the card object that resides
//at this location in the array
var card:Object = aGrid[i][j];
//the definition for the backside (visible part for the card
var img : String;
//check if the card is face up, if so, show the robot part
//if not show the wrench
if(card.ifFaceUp)
{
img = card.img;
}
else
{
img = "wrench";
}
//create a button using a picture instead of
//text. Getting the picture from the Resources
if(GUILayout.Button(Resources.Load(img),
GUILayout.Width(cardW)))
{
flipCardFaceUp(card);
//print to the debug the name of the picture
Debug.Log(card.img);
}
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
}//end buildGrid
Class where ifFaceUP and img are defined
class Card extends System.Object
{
//is the card face up
var ifFaceUp:boolean = false;
//has the card been matched
var ifMatched:boolean = false;
//image for the card
var img: String;
//constructor
function Card(img : String)
{
this.img = img;
}
}
errors: http://puu.sh/2clHw

Looking at the script you emailed I can see that aGrid contains Objects of type Card. In ECMA JavaScript nothing is strongly typed. ECMA is the JS that runs in the browser. Your JS is .net code that runs on the server when the browser requests a certain page or used as a desktop application (not sure what type of app it is). Even though it's called JavaScript it only means that the syntax looks like JavaScript but since it's .net code it's completely different from JavaScript (ECMA).
One thing you can do with ECMA JS is:
var notStronglyTyped=22; // is int
notStronglyTyped = "hello";// changed to string
notStronglyTyped.subString();// can call subString now because it's a method of string
This will not work in .net since .net is strongly typed (and class based but that's not the problem at hand). Hence the int when you declare a variable:
var i:int=0;// the :int gives a syntax error in ECMA JS since it doesn't exist.
Strongly typed means that the variable needs to be declared or converted to a certain type before you execute functions or access properties that are accociated with that type. substring is a method of String but I can't call it on an int:
var i:int=0;
i.subString();//won't work in .net unless you cast it to another type.
((String)i).subString();//might work but I don't know the exact syntax for .net JS.
In short; when retrieving cards from aGrid I would suggest declaring them as Card since you don't need to type cast later when you declare it as Object. The array aGrid contains objects of type Card anyway so you should not get a warning or error there:
card = new Card("robot" + (i+1) + "Missing" + theMissingPart);
//instance card is of type Card
aCards.Add(card);//aCards contains items of type Card
....
aGrid[i][j] = aCards[somNum];
//aGrid is filled with items from aCards which in turn contains items of type Card
At some point in your code you do:
var card:Object = aGrid[i][j];
I am not sure why since aGrid contains Card type (everything is type Object because everything inherits from Object). So why not declare the variable card as an instance of Card?
var card:Card = aGrid[i][j];
That should solve your problem right there. I can't run the code here because I have not set up a .net develop environment but I'm sure that solves it.
You can look up articles on google on type casting (wikipedia) you can imagine the headaches that come with it when you fill an array or list with mixed types. This is where generics can lend a helping hand but it might be too early to get into that as it can make your head explode :-)

Related

javascript how to insert new elements at different locations in page

I'm writing a chrome extension that will add helper text instructions/reminders to specific location in the "new order" form we use at work. I'm really new to coding (basically using this project as a way to learn). I've created something that works - but I'm convinced there's a more elegant solution that I just haven't been able to figure out.
var helpText = "this is the message"
var customAlert = makeAlert(helpText) //create html container for msg
function makerAlert(helpText){...} //createElem, add class/style, append children
I'm okay with that bit (above). But should i be storing information on each message in objects instead? why would/wouldn't i? what information would go in it?
function alertPlacer(customAlert){
var par = document.getElementsByClassName("class-name")[i];
var sib = par.childNodes[j];
par.insertBefore(customAlert, sib);
};
really struggling with this bit (above). I have actually made alertPlacer() functions for each message because i can't figure out how to create a function that will take different class name & index parameters. should i be breaking this up more? if i stored these bits of info in an object, would that be useful?
relevant info:
because the target locations are within a form, almost nothing has an "id" attribute. so i have to use getElementsByClassName & an index.
for each message, I know the target parent className & index and the child node index to "insert before".
i would like to stick with javascript-only solution.
functions can take multiple arguments:
function alertPlacer(customAlert,className,parIndex,childIndex){
var par = document.getElementsByClassName(className)[parIndex]; var sib = par.childNodes[childIndex];
par.insertBefore(customAlert, sib);
};
And you call your function like
alertPlacer(yourAlert,"class-name",6,9);

collection object recognition in Descriptive Programming in QTP

Good evening, I am a beginner to QTP, I need help, I developed a complex procedure for the reading of the tariffs within a page (developed in Javascript) and programming with powerful descriptive, for each share untreated, recognize the object .getROProperty ("InnerText") and put it in a variable for me with databases.
Indexes are many but all have the same properties (micclass, html tags) only changes the class and html id.
Class and html id recover them to function as a dataTable.
I have created a specific function that deals with the reading of the indices on the basis of a pair of collection value able to define only the object.
This is the part of script (function) that i need to recognize objects:
Function recover_q_cvq (q_cvq_ogg, ogg_class)
' Dim variables
Dim object_collection
Dim r_object
Dim rate_cvq
Dim count_object
Dim rate_trim
print "Object:" & q_cvq_ogg
print "Class:" & ogg_class
' recover rate with object collection, micclass, html tag, class, html id
Set object_collection = Description.Create()
object_collection("micclass").Value = "WebElement"
object_collection("html tag").Value = "DIV"
object_collection("class").Value = ogg_class
object_collection("html id").Value = q_cvq_ogg
object_collection("visible").Value = "True"
Set r_object = Browser("(H) Gestione Quote").Page("(H) Gestione Quote").ChildObjects(object_collection)
r_object.RefreshObject
count_object = r_object.count
If count_object = 1 Then
rate_cvq = r_object(0).getROProperty("innertext")
print "Object rate: " &rate_cvq
rate_trim_cvq = Replace(rate_cvq,",","")
recover_q_cvq = rate_trim_cvq
'empty variables object_collection,r_object,count_object
Set object_collection = nothing
Set r_object = nothing
Set count_object = nothing
Else
print "Object is not collected"
print "Error:" & err.number
print DescribeResult(err.number)
End if
End Function
The script works well and I have the variable rate_cvq object that interests me only during the execution often that QTP stops recognize the object suddenly, for no apparent reason, and despite the collection is not complete and therefore not recognize the ChildObject collects the object. When it happens from then on no object is recognized until the end of the test.
This anomaly occurs randomly and never at the same point and this, the same rate in an execution is detected while in another not. This makes me think that the script does not have problems.
Can someone please help me? I have to add some other property to the script? where am I wrong? Thank you very much in advance for your reply.
Cristiano

Accessing values in javascript

I am using a JS library for facetracking/emotion detection called CLMtracker.
http://auduno.github.io/clmtrackr/examples/clm_emotiondetection.html
Note: Seems to work best in chrome for those trying to use it.
Is the example I am using, I am wondering how I can access the values for each emotion. For instance, I want check every 10 seconds what the values are and print to console. From this I would also like to compare the values to find the highest and find the emotion that is attached to that. I think I am right in saying that the max() function will give me the highest out of an array?
What I have tried:
I have tried to get emotionData[0].emotion and emotionData[0].value which should print Angry and the value, but it only prints 0. I have also tried the same method with data which does not seem to return anything.
EDIT
emotionData gets me:
however it does not seem to show any update/change as I make my expression change
ec.meanPredict(ctrack.getCurrentParameters()) returns an object containing all the current scores for all emotions.
To get the current score of "Angry", for example, you would do :
ec.meanPredict(ctrack.getCurrentParameters())[0].value
So, in order to get the current most probable emotion, you could do this :
function getCurrentEmotion()
{
if(!ec.meanPredict(ctrack.getCurrentParameters())){setTimeout(getCurrentEmotion,1000);return;}
var currentData = ec.meanPredict(ctrack.getCurrentParameters());
var currentScores = [];
//Gather all scores in an array
for(var i=0;i<currentData.length;i++)
{
currentScores.push(currentData[i].value);
}
//Get the biggest score
var max = Math.max.apply(null,currentScores);
//Calculate its index
var indexOfScore = currentScores.indexOf(max);
//Get the associated emotion
var emotion = currentData[indexOfScore].emotion;
console.log(emotion);
//Set up a loop (did not add 'var', to allow stopping it from outside)
currentEmotionLoop = setTimeout(getCurrentEmotion,3000);
}
To stop the loop at any time, do this :
clearTimeout(currentEmotionLoop);
By the way, the ec variable is declared privately, so in order for this to work, either remove var where it is declared :
var ec = new emotionClassifier();
or write this code in the same file, under the same scope.

Cannot get unique values in card array

I am new to programming and javascript and i have a question ive been struggling with for a bit now. Im trying to build a card game and have a card object which returns a card representation of the format (card #,suit eg. 5,Hearts). I deal a card at the start of the program and validate that the card dealt is unique (ie not been used already). I have the following structure:
var usedCards= [];
function dealCards() {
for (i = 0; i < 3; i++)
{
var card = createUniqueCard();
usedCards.push(card.cardRepresentation);
}
}
function createUniqueCard() {
do {
var newCard = new Card();
}
while (usedCards.indexOf(newCard.cardRepresentation) != -1);
return newCard;
}
This still returns me duplicate cards in my usedCards array. Can anyone point out my logic error?
Thanks
If newCard.cardRepresentation is an object then .indexOf() will never find a match because two object references are considered equal only if they refer to the same instance - you keep creating new instances with new Card().
If you can have newCard.cardRepresentation as a string it should work. Or if you write your own function to replace .indexOf(), where your function knows how to compare two .cardRepresentation objects...
I think a better solution is to begin by generating all possible cards, putting them in an array, and then your deal function could randomly select from that array.

Removing items from data bound array

How do I remove an items from a data bound array? My code follows.
for(var i = 0; i < listBox.selectedIndices.length; i++) {
var toRemove = listFiles.selectedIndices[i];
dataArray.splice(toRemove, 1);
}
Thanks in advance!
Edit Here is my swf. The Add Photos works except when you remove items.
http://www.3rdshooter.com/Content/Flash/PhotoUploader.html
Add 3 photos different.
Remove 2nd photo.
Add a different photo.
SWF adds the 2nd photo to the end.
Any ideas on why it would be doing this?
Edit 2 Here is my code
private function OnSelectFileRefList(e:Event):void
{
Alert.show('addstart:' + arrayQueue.length);
for each (var f:FileReference in fileRefList.fileList)
{
var lid:ListItemData = new ListItemData();
lid.fileRef = f;
arrayQueue[arrayQueue.length]=lid;
}
Alert.show('addcomplete:' + arrayQueue.length);
listFiles.executeBindings();
Alert.show(ListItemData(arrayQueue[arrayQueue.length-1]).fileRef.name);
PushStatus('Added ' + fileRefList.fileList.length.toString() + ' photo(s) to queue!');
fileRefList.fileList.length = 0;
buttonUpload.enabled = (arrayQueue.length > 0);
}
private function OnButtonRemoveClicked(e:Event):void
{
for(var i:Number = 0; i < listFiles.selectedIndices.length; i++) {
var toRemove:Number = listFiles.selectedIndices[i];
//Alert.show(toRemove.toString());
arrayQueue.splice(toRemove, 1);
}
listFiles.executeBindings();
Alert.show('removecomplete:' + arrayQueue.length);
PushStatus('Removed photos from queue.');
buttonRemove.enabled = (listFiles.selectedItems.length > 0);
buttonUpload.enabled = (arrayQueue.length > 0);
}
It would definitely be helpful to know two things:
Which version of ActionScript are you targeting?
Judging from the behavior of your application, the error isn't occurring when the user removes an item from the list of files to upload. Looks more like an issue with your logic when a user adds a new item to the list. Any chance you could post that code as well?
UPDATE:
Instead of: arrayQueue[arrayQueue.length]=lid
Try: arrayQueue.push(lid)
That will add a new item to the end of the array and push the item in to that spot.
UPDATE 2:
Ok, did a little more digging. Turns out that the fileList doesn't get cleared every time the dialog is opened (if you're not creating a new instance of the FileReferenceList each time the user selects new files). You need to call splice() on the fileList after you add each file to your Array.
Try something like this in your AddFile() method...
for(var j:int=0; j < fileRefList.fileList.length; j++)
{
arrayQueue.push(fileRefList.fileList[j]);
fileRefList.fileList.splice(j, 1);
}
That will keep the fileList up to date rather than holding on to previous selections.
I see one issue. The selected indices are no longer valid once you have spliced out the first element from the array. But that should only be a problem when removing multiple items at once.
I think we need to see more code about how you are handling the upload before we can figure out what is going on. It looks to me like you are holding a reference to the removed FileReference or something. The described problem is occurring when you upload a new file, not when you remove the selected one.
Do you mean to use listBox and listFiles to refer to the same thing?
I'm stepping out on a limb here, because I don't have a ton of experience with JavaScript, but I'd do this the same way that I'd do it in C, C++, or Java: By copying the remaining array elements down into their new locations.
Assuming that listFiles.selectedIndices is sorted (and its contents are valid indices for dataArray), the code would be something like the following:
(WARNING: untested code follows.)
// Don't bother copying any elements below the first selected element.
var writeIndex = listFiles.selectedIndices[0];
var readIndex = listFiles.selectedIndices[0] + 1;
var selectionIndex = 1;
while(writeIndex < (dataArray.length - listFiles.selectedIndices.length)) {
if (selectionIndex < listFiles.selectedIndices.length) {
// If the read pointer is currently at a selected element,
// then bump it up until it's past selected range.
while(selectionIndex < listFiles.selectedIndices.length &&
readIndex == listFiles.selectedIndices[selectionIndex]) {
selectionIndex++;
readIndex++;
}
}
dataArray[writeIndex++] = dataArray[readIndex++];
}
// Remove the tail of the dataArray
if (writeIndex < dataArray.length) {
dataArray.splice(writeIndex, dataArray.length - writeIndex);
}
EDIT 2009/04/04: Your Remove algorithm still suffers from the flaw that as you remove items in listFiles.selectedIndices, you break the correspondence between the indices in arrayQueue and those in listFiles.selectedIndices.
To see this, try adding 3 files, then doing "Select All" and then hit Remove. It will start by removing the 1st file in the list (index 0). Now what had been the 2nd and 3rd files in the list are at indices 0 and 1. The next value taken from listFiles.selectedIndices is 1 -- but now, what had been the 3rd file is at index 1. So the former File #3 gets spliced out of the array, leaving the former 2nd file un-removed and at index 0. (Using more files, you'll see that this implementation only removes every other file in the array.)
This is why my JavaScript code (above) uses a readIndex and a writeIndex to copy the entries in the array, skipping the readIndex over the indices that are to be deleted. This algorithm avoids the problem of losing correspondence between the array indices. (It does need to be coded carefully to guard against various edge conditions.) I tried some JavaScript code similar to what I wrote above; it worked for me.
I suspect that the problem in your original test case (removing the 2nd file, then adding another) is analogous. Since you've only shown part of your code, I can't tell whether the array indices and the data in listFiles.selectedIndices, arrayQueue, and fileRefList.fileList are always going to match up appropriately. (But I suspect that the problem is that they don't.)
BTW, even if you fix the problem with using splice() by adjusting the array index values appropriately, it's still an O(N2) algorithm in the general case. The array copy algorithm is O(N).
I'd really need to see the whole class to provide a difinitive answer, but I would write a method to handle removing multiple objects from the dataProvider and perhaps assigning a new array as the dataProvider for the list instead of toying with binding and using the same list for the duration. Like I said, this is probably inefficient, and would require a look at the context of the question, but that is what I would do 9unless you have a big need for binding in this circumstance)
/**
* Returns a new Array with the selected objects removed
*/
private function removeSelected(selectedItems:Array):Array
{
var returnArray:Array = []
for each(var object:Object in this.arrayQueue)
{
if( selectedItems.indexOf(object)==-1 )
returnArray.push( object )
}
return returnArray;
}
You might be interested in this blog entry about the fact that robust iterators are missing in the Java language.
The programming language, you mentioned Javascript, is not the issue, it's the concept of robust iterators that I wanted to point out (the paper actually is about C++ as the programming language).
The [research document]() about providing robust iterators for the ET++ C++ framework may still e helpful in solving your problem. I am sure the document can provide you with the necessary ideas how to approach your problem.

Categories