I am using the following code to check for values of 1 or 0 stored in a dictionary file called 'myDict'. At position 'block003stored' is the value 1 and at all the other positions it's 0. If I use the following code I always get 0 returned for all positions:
for (int i = 1 ; i < 100 ; i++) {
if(myDict)
{
UIImageView *imageV = (UIImageView *)[self.view viewWithTag:i];
int myInt = [[myDict objectForKey:#"block%.3istored"] intValue];
NSLog (#"value of i %d", i);
NSLog (#"myInt %d", myInt);
if (myInt == 1) imageV.hidden = FALSE;
}
}
}
However if I change the objectForKey to specifically #"block003stored":
int myInt = [[myDict objectForKey:#"block003stored"] intValue];
I get the correct value of 1 returned. I can't see why the code isn't working when I use the %.3i instead of 001, 002, 003 etc?
Try in a separate line:
NSString *indexStr = [NSString stringWithFormat:#"block%.3dstored", i]; Then use the objectForKey:indexStr];
You were asking the dictionary to get the object with the key of "block%.3istored", which didn't exist. You need to apply formatting to get i in there.
The code in the loop is using #"block%.3istored" as a literal string. There's nothing in what you've written to format the string with the i variable. Look at NSString's stringWithFormat: as a way of dynamically building the key.
Related
I'm creating a Plinko type game and need to generate a random number -- either a 0 or a 1 -- 136 times and store it in an array of 136 elements. In other words, the value of each of the 136 elements will either be the integer 0, or the integer 1, randomly chosen.
The following code randomly produces a 0 or a 1, 136 times:
for (var i:int = 0; i < 136; i++) {
var randNum:Number = Math.floor (Math.random()*2);
}
trace(randNum);
Hence, I have the the first portion of the code done. What I don't know how to do is the second part: storing the 136 integers (0 or 1) in an array.
The following video gives an example of how to perform such a task in C++ :
https://www.youtube.com/watch?v=z0PqC2HCkL8
But I'm new to all this and don't know how to write such a function for ActionScript 3.0.
I would appreciate any help.
Math.random() returns a number between 0 and 1, so you can simply use Math.round(arg) to get an integer.
const numbers: Vector.<int> = new Vector.<int>();
for (var i: int = 0; i < 136; i++) {
numbers.push(Math.round(Math.random()));
}
That worked great, thanks. I substituted Array for Vector. The trace output shows it to be working perfectly.
var numbers: Array = new Array();
for (var i: int = 0; i < 136; i++) {
numbers.push(Math.round(Math.random()));
}
trace (numbers);
trace (numbers.length);
trace (numbers[0]);
I have an array where each element comes from a line delimited by tab.
Initial code:
#!/usr/bin/perl -w
use strict;
The code below is a piece of the code.
sub parser_domains {
my #params = #_;
my $interpro_line = "";
my #interpro_vector = ( );
my $idr_sub_id = $params[0];
my $idr_sub_start = $params[1]+1;
my $idr_sub_end = $params[2]+1;
my $interpro_id = "";
my $interpro_start_location = 0;
my $interpro_end_location = 0;
my $interpro_db = "";
my $interpro_length = 0;
my $interpro_db_accession = "";
my $interpro_signature = "";
my $interpro_evalue = "";
my $interpro_vector_size = 0;
my $interpro_sub_file= "";
my $idr_sub_lenght = ($idr_sub_end-$idr_sub_start)+1;
$interpro_sub_file = "$result_directory_predictor/"."$idr_sub_id/"."$idr_sub_id".".fsa.tsv";
#open file; if it fails, print a error and exits.
unless( open(TSV_FILE_DATA, $interpro_sub_file) ) {
print "Cannot open file \"$interpro_sub_file\"\n\n";
return;
}
my #interpro_file_line = <TSV_FILE_DATA>;
close TSV_FILE_DATA;
foreach $interpro_line (#interpro_file_line) {
#interpro_vector = split('\t',$interpro_line);
$interpro_id = $interpro_vector[0];
$interpro_db = $interpro_vector[3];
$interpro_db_accession = $interpro_vector[4];
$interpro_start_location = $interpro_vector[6];
$interpro_end_location = $interpro_vector[7];
$interpro_signature = $interpro_vector[11];
$interpro_length = ($interpro_end_location-$interpro_start_location) + 1;
if ($interpro_signature eq ""){
$interpro_signature = "NOPIR";
printf IDP_REGION_FILE "\nFound a $interpro_db domain with no IPR: starts at $interpro_start_location and ends at $interpro_end_location\n";
printf IDP_REGION_FILE "The size of $interpro_db domain in the sequence is $interpro_length\n";
printf IDP_REGION_FILE "The IDR starts at $idr_sub_start and and ends at $idr_sub_end\n";
printf IDP_REGION_FILE "The size of IDR is $idr_sub_lenght\n";
domains_regions($idr_sub_start,$idr_sub_end,$interpro_start_location,$interpro_end_location,$interpro_signature,$interpro_length,$interpro_db,$idr_sub_id,$interpro_db_accession,$idr_sub_lenght);
}
else{
for $entry_line (#entry_file_line) {
#entry_vector = split('\t',$entry_line);
$entry_ac = $entry_vector[0];
$entry_type = $entry_vector[1];
$entry_name = $entry_vector[2];
chomp($entry_name);
if ($interpro_signature eq $entry_ac) {
printf IDP_REGION_FILE "\nFound a $interpro_db domain with Interpro Signature $entry_ac: starts at $interpro_start_location and ends at $interpro_end_location\n";
printf IDP_REGION_FILE "The size of $interpro_db domain in the sequence is $interpro_length\n";
printf IDP_REGION_FILE "The Interpro Signature $entry_ac belongs to type $entry_type\n";
printf IDP_REGION_FILE "The name of $entry_ac is $entry_name\n";
printf IDP_REGION_FILE "The IDR starts at $idr_sub_start and ends at $idr_sub_end\n";
printf IDP_REGION_FILE "The size of IDR is $idr_sub_lenght\n";
domains_regions($idr_sub_start,$idr_sub_end,$interpro_start_location,$interpro_end_location,$interpro_signature,$interpro_length,$interpro_db,$idr_sub_id,$interpro_db_accession,$idr_sub_lenght);
}
}
}
}
}
A example of tsv file (interproscan):
P51587 14086411a2cdf1c4cba63020e1622579 3418 Pfam PF09103 BRCA2, oligonucleotide/oligosaccharide-binding, domain 1 2670 2799 7.9E-43 T 15-03-2013
P51587 14086411a2cdf1c4cba63020e1622579 3418 ProSiteProfiles PS50138 BRCA2 repeat profile. 1002 1036 0.0 T 18-03-2013 IPR002093 BRCA2 repeat GO:0005515|GO:0006302
P51587 14086411a2cdf1c4cba63020e1622579 3418 Gene3D G3DSA:2.40.50.140 2966 3051 3.1E-52 T 15-03-2013
...
The scripts works perfectly, but the comparison $interpro_signature eq "" provides a warning.
Use of uninitialized value $interpro_signature in string eq at /home/duca/eclipse-workspace/idps/idp_parser_interpro.pl line 666.
So, I searched and tried manners to replace the empty value into the array before the comparison. I would like the empty value by "NOIPR".
I'm working with 9 completed genomes, and I have more than 324000 proteins to parse.
How can I replace the empty values in my array?
Thanks.
Your array may not have 12 elements (or the 12-th element may be undef)
my $interpro_signature = $interpro_vector[11] // 'some_default_value';
The // is the defined-or operator.
The error Use of uninitialized value means that the variable hasn't been initialized, or it's been set to undef.
See perldiag and use it regularly. Run code with perl -Mdiagnostics ... on errors, regularly.
The use warnings; is actually better than -w.
Update to a substantial edit of the question
From shown data it appears that yet other fields may not be given in the file; so proof all variables with defaults, much like for the array element at index 11 above. This is what you want to do in general anyway. For example, if there are all fields in the file but some may be empty (two tabs with nothing in between)
my #interpro_defaults = ('id_default', 'db_default', ...);
my ($interpro_id, $interpro_db, ...) =
map {
$interpro_vector[$_] // $interpro_defaults[$_]
} 0 .. $#interpro_defaults;
This relies on order (of variables) in the list, what can be error prone with variables; see below.
If some fields are simply not there there may be (far) more work to do.
There are too many separate variables, all related and named as $interpro_X (and then there are $idr_Y and $entry_Z, but fewer and perhaps manageable).
Can you not bundle them in a container-type variable or a data structure?
A hash %interpro seems suitable, with keys X (so, $interpro{id} etc). Then you can use them more easily and can perform some actions on the whole lot. You still have to watch for order when initializing since they are read sequentially, but it should be clearer this way. For example
my #interpro_vars = qw(id db db_accesssion ...);
my #interpro_vector = qw(id_default db_default ...);
my %interpro;
#interpro{#interpro_vars} = #interpro_vector;
# or simply
#interpro{qw(id db ...)} = qw(id_default db_default ...);
I've defined arrays with keys and values first and then used them, in case that you may want to later have those lists in arrays. If that's not the case you can initialize the hash with lists (the last line).
Here
my %h;
#h{LIST-keys} = LIST-values;
is a way to assign the list of LIST-values to the set of keys of the hash %h given in LIST-keys. They are assigned one for one, in the given order of both lists (which had better match in size). There is the # sigil in front of hash's keys since we are having a list (of keys) there, not a hash. Note that the hash must have been declared somewhere. See slices in perldata.
The problem is that your 3rd line contains only 9 elements. So
#interpro_vector = split('\t',$interpro_line);
for that line assigns only 9 elements to #interpro_vector but you then access $interpro_vector[11] (i.e. the 12th element) and that doesn't exist. You can now either check that #interpro_vector contains (at least) 12 elements:
if (#interpro_vector >= 12) {
...
}
Or you can use the defined-or operator as #zdim suggested to use a default value in case $interpro_vector[11] isn't defined:
$interpro_signature = $interpro_vector[11] // '';
The above line is equivalent to
if (defined $interpro_vector[11]) {
$interpro_signature = $interpro_vector[11];
} else {
$interpro_signature = '';
}
Now
if ($interpro_signature eq "") {
...
}
will work.
I have the following code:
console.log("start");
for(var i = 0; i < array.length; i++){
console.log(i + " = " + array[i]);
}
console.log(array);
console.log("end");
This gives me the following output:
[16:34:41.171] start
[16:34:41.171] 0 = 0
[16:34:41.172] 1 = 168
[16:34:41.172] 2 = 171
[16:34:41.172] [0, 168, 171, 139]
[16:34:41.172] end
That is, it doesn't show the 139 element when iterating the array, but console.log does print it when outputting the whole array. WHY? (<-- the question)
I do modify the array later on, is the console.log somehow delayed until after I changed the array? Note tho that change the order of the statements, and putting consoel.log(array) directly at the start does not change the outcome (still different outputs).
I am using firefox 20.0
Update: If you want to see this behavior, copy and paste the code in the console and execute. Then close developer tools and open again, apparently the pointer thing only happens when the code is executed in the background(which happens when you reopen the console).
Console.log output of objects, is a pointer, no a real value. This means that if the object changes later, console.log object will be updated. Try:
console.log("start");
var array = [1];
for(var i = 0; i < array.length; i++){
console.log(i + " = " + array[i]);
}
console.log(array);
console.log("end");
array.push(9999);// you will see the 9999 in the console no matter it was added after the output.
To prevent pointer issues try this:
console.log(array.join()); because later in some point of your application you are adding the 139 value.
I want to Put two arrays value in LinkedHashMap as key-value.
Here is the snippet that I'm using:
String[] s = answer.split("\\,");
String[] ss = aa.split("\\,");
System.out.println(ss.length); -->prints 3
System.out.println(s.length); -->prints 3
What I want is to put s values as Key and ss values as Value in HashMap.
I'm trying to write code.
for(int i=0;i<s.length;i++){
for(int j= 0;j<ss.length;j++){
if(s[i].length()==s[j].length()){
testMap.put(s[i], ss[j]);
}
}
}
But unable to Put into Map. What I've done wrong?
And I'm using LinkedHashMap to preserve the order of Insertion.
Here is the solution:
for(int i=0;i<s.length;i++){
testMap.put(s[i], ss[i]);
}
I just have to change my loop condition to this. Instead of using two for loops.
Thanks everybody.
Use this code, It will add accordingly
String answer = "ID,NAME,VALUES";
String aa = "1,KLAXXON,ROMEO";
String[] s = answer.split("\\,");
String[] ss = aa.split("\\,");
for (int i = 0; i < s.length; i++) {
testMap.put(s[i], ss[i]);
}
Output:
{ID=1, NAME=KLAXXON, VALUES=ROMEO}
I'm collecting rows of answers from a database which are made in to arrays. Something like:
for (var i:int = 0; i < event.result.length; i++) {
var data = event.result[i];
var answer:Array = new Array(data["question_id"], data["focus_id"], data["attempts"], data["category"], data["answer"], data["correct"], data["score"]);
trace("answer: " + answer);
restoreAnswer(answer, i);
}
Now, if I trace answer, I typically get something like:
answer: 5,0,2,IK,1.a,3.1,0
answer: 5,0,1,IK,2.a,3.1,0
answer: 4,1,1,AK,3,3,2
From this we see that focus_id 0 (second array item) in question_id 5 (first array item) has been attempted twice (third array item), and I only want to use the last attempt in my restoreAnswer function.
My problem is that first attempt answers override the second attempts since the first are parsed last it seems. How do I go about only calling my restoreAnswer only when appropriate?
The options are:
1 attempts, correct score (2 points)
2 attempts, correct score (1 points)
1 attempt, wrong score (0 points)
2 attemps, wrong score (0 points)
There can be multiple focus_id in each question_id.
Thank you very much! :)
I would consider having the DB query return only the most recent attempt, or if that doesn't work efficiently, return the data in attempt order. You may score question 5 twice, but at least it'll score correctly on the last pass.
You can also filter or sort the data you get back from the server.
Michael Brewer-Davis suggested using the database query to resolve this; normally speaking, this would be the right solution.
If you wait until you get it back from the web method call or whatever in AS3, then consider creating an additional Vector variable:
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
You mentioned that it seems that everything is sorted so that earlier attempts come last. First you want to make sure that's true. If so, then before you do any call to restoreAnswer(), you'll want to check vAttempts to make sure that you have not already called restoreAnswer() for that question_id and focus_id:
if (!vAttempts[data["question_id"]])
{
vAttempts[data["question_id"]] = new Vector.<int>(); // ensuring a second dimension
}
if (vAttempts[data["question_id"]].indexOf(data["focus_id"]) == -1)
{
restoreAnswer(answer, i);
vAttempts[data["question_id"]].push(data["focus_id"]);
}
So optimizing this just a little bit, what you'll have is as follows:
private final function resultHandler(event:ResultEvent):void {
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
var result:Object = event.result;
var iLength:int = result.length;
for (var i:int = 0; i < iLength; i++) {
var data = result[i];
var iQuestionID:int = data["question_id"];
var iFocusID:int = data["focus_id"];
var answer:Array = [iQuestionID, iFocusID, data["attempts"],
data["category"], data["answer"], data["correct"], data["score"]];
trace("answer: " + answer);
var vFocusIDs:Vector.<int> = vAttempts[iQuestionID];
if (!vFocusIDs) {
vAttempts[iQuestionID] = new <int>[iFocusID];
restoreAnswer(answer, i);
} else if (vFocusIDs.indexOf(iFocusID) == -1) {
restoreAnswer(answer, i);
vFocusIDs.push(iFocusID);
}
}
}
Note: In AS3, Arrays can skip over certain indexes, but Vectors can't. So if your program doesn't already have some sort of foreknowledge as to the number of questions, you'll need to change vAttempts from a Vector to an Array. Also account for whether question IDs are 0-indexed (as this question assumes) or 1-indexed.