mode de synchronisation?Salut à tous,
Je me bats avec les parties asynchrones de JMP / JSL. Je comprends maintenant que vous pouvez utiliser "Run Formulas ()" pour forcer l'évaluation d'une formule avant de l'utiliser, mais j'ai des problèmes similaires avec d'autres fonctions:
Lorsque la valeur est utilisée, cela peut être incorrect. C'est très dangereux!
Existe-t-il un "mode de synchronisation forcée" dans lequel JSL procède instruction par instruction et attend systématiquement qu’il soit terminé avant de passer au suivant?
Exemple de mes problèmes actuels, j'extrais les valeurs d'une sélection de lignes (selRows) d'une table (dt) pour remplir une ligne dans une autre table (sumdt):
thisCol = Column(sumdt, thisName||"_Q10");
valueSet = Column(dt, colList[i])[selRows];
thisValue = Quantile(0.10, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q25");
thisValue = Quantile (0.25, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q50");
thisValue = Quantile (0.50, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q75");
thisValue = Quantile (0.75, valueSet);
thisCol[] = thisValue;
thisCol = Column(sumdt, thisName||"_Q90");
thisValue = Quantile (0.90, valueSet);
thisCol[] = thisValue;Cela fonctionne PARFOIS! Mais parfois, toutes les données de la colonne sumdt ont exactement la même valeur et parfois, rien ne sort du tout.
Je sais que certains recommandent la commande wait (0), mais j'ai lu quelqu'un qui disait que ce n'était pas une garantie non plus.
Alors, comment puis-je m'assurer que les calculs sont complétés?
Merci!
Re: mode de synchronisation?AAARGH!
J'ai trouvé le problème, c'était ... données entrantes!
J'ai figuré que certaines colonnes sur certains fichiers ont un nom identique à celui du principal au début, juste avec un chiffre différent (que je dépouille), MAIS avec une seule valeur, donc ça va les statistiques!
Mes sincères excuses pour ce qui est trompeur! J'ai encore appris de bonnes pratiques, donc je suis reconnaissant.
Merci à tous pour votre soutien!
Re: mode de synchronisation?Répondre à moi-même:
Non, ce n'est pas la fonction statistique, c'est la façon dont je récupère les valeurs. Les nombres entrent mal.
Re: mode de synchronisation?J'ai corrigé les deux et cela n'a pas changé mon problème.
Je ne crois plus que ce soit une condition de concurrence. C'est assez systématique et se passe au même endroit sur les mêmes ensembles de données. J'ai essayé de mélanger l'ordre des éléments ou de réduire l'étendue d'un élément à la fois, de placer le dev std comme premier calcul, de modifier l'ordre des éléments et j'ai toujours les mêmes chiffres exacts, faux ou manquants.
Existe-t-il des bogues connus sur les fonctions statistiques 12.1?
Re: mode de synchronisation?- retirer le table de données actuelle (dt); et utilisez un dt explicite si nécessaire. la date actuelle des données peut changer si vous cliquez sur une table alors que le JSL est en cours d'exécution.
- n'utilisez pas la colonne [/ * entre crochets vides sans indice * /] sauf si vous définissez une ligne en cours. Le [] vide signifie "la ligne en cours". Les crochets vides ne sont généralement pas nécessaires. Votre exemple nécessite probablement un indice de ligne explicite.
Re: mode de synchronisation?Re-bonjour,
Merci pour votre réponse et votre perspicacité.
Malheureusement, j'ai toujours les mêmes problèmes: valeurs manquantes, valeurs en double dans le jeu de résultats (de Q10 à Mean, StdDev manquant).
J'ai essayé plusieurs choses. J'ai fait un indice sur le côté pour vérifier quelques valeurs anormales "manuellement" et elles sont bien sorties.
J'ai ajouté de nombreuses déclarations "d'attente".
Je suis assez à court d'idées!
Voici le script (presque tout, enlevé quelques vérifications de l'existence de colonnes, etc., il est assez gros):
Names Default To Here(1);
dt = Current Data Table();
colNames = dt << Get Column Names (String);
Summarize(itemsList = by("Item"));
binsList = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"};
colNamesSum = sumdt << Get Column Names (String);
For (k=1, k <= Nitems(itemsList), k++,
itemID = itemsList[k];
dt << Select All Rows << Exclude(0);
dt << Select Where (dt:Item == itemID);
itemRows = dt << Get Selected Rows;
prodID = Right(Column (dt, "proc_id")[itemRows[1]],4);
lotID = Regex(Column(dt, "lot_id")[itemRows[1]], "\d{6}");
show(lotID,itemID);
checkDup = sumdt << Get Rows Where (:Lot == lotID & :Item == itemID);
If(NRows(checkDup) == 0,
newIt = 1;
show(newIt);
sumdt << AddRows(1);
Column(sumdt, "Test Date")[] = Column(dt, "finish_t")[itemRows[1]];
Column(sumdt, "Item")[] = itemID;
Column(sumdt, "N ")[] = NRow(itemRows);
Column(sumdt, "Product")[] = prodId;
Column(sumdt, "Lot")[] = lotID;
dt << Invert Row Selection << Exclude(1);
Current Data Table(dt);
Summarize(bins = by(:SBIN_NUM), countTable = count());
dt << Select All Rows << Exclude(0);
Current Data Table(sumdt);
For (i=1, i <= Nitems(binsList), i++,
binPos = Contains(bins, binsList[i]);
Column(sumdt, "Bin"||binsList[i])[] =
If(binPos == 0, 0, countTable[binPos]);
);
colNamesSum = sumdt << Get Column Names (String);
For (i=1, i<= Nitems(colList), i++,
thisName = colNames[colList[i]];
show(thisName);
valueSet = Column(dt, colList[i])[itemRows];
thisValueQ10 = Quantile(0.10, valueSet);
wait(0);
thisValueQ25 = Quantile (0.25, valueSet);
wait(0);
thisValueQ50 = Quantile (0.50, valueSet);
wait(0);
thisValueQ75 = Quantile (0.75, valueSet);
wait(0);
thisValueQ90 = Quantile (0.90, valueSet);
wait(0);
thisValueMean = Mean (valueSet);
wait(0);
thisValueStdDev = Std Dev (valueSet);
wait(0);
show(thisValueStdDev);
thisColQ10 = Column(sumdt, thisName||"_Q10");
thisColQ25 = Column(sumdt, thisName||"_Q25");
thisColQ50 = Column(sumdt, thisName||"_Q50");
thisColQ75 = Column(sumdt, thisName||"_Q75");
thisColQ90 = Column(sumdt, thisName||"_Q90");
thisColMean = Column(sumdt, thisName||"_Mean");
thisColStdDev = Column(sumdt, thisName||"_StdDev");
thisColQ10[] = thisValueQ10;
thisColQ25[] = thisValueQ25;
thisColQ50[] = thisValueQ50;
thisColQ75[] = thisValueQ75;
thisColQ90[] = thisValueQ90;
thisColMean[] = thisValueMean;
thisColStdDev[] = thisValueStdDev;
);
show("Item completed"),
newIt = 0;
show(newIt);
show("Item already exists in summary table!");
New Window("WARNING",
<< modal,
Text Box("Item "||lotId||"-"||itemID||" already in the table"),
Text Box("Skipping this item"),
Button Box("OK")
);
);
);
show("Lot completed");
sumdt << Save();Re: mode de synchronisation?Dans ma dernière réponse, j'ai utilisé un petit tableau qui ne mettrait pas nécessairement en évidence les problèmes de synchronisation. S'il y a un retard, ce sera le calcul des quantiles. Le code ci-dessous calcule un quantile pour 10 millions de points de données. La fonction s'exécute de manière synchrone comme prévu, c'est-à-dire que l'émission n'est pas exécutée tant que la valeur de q n'a pas été établie. S'il y avait un problème de synchronisation, nous verrions la valeur de q affichée comme zéro.
vals = J(10000000,1,Random Normal());
q = 0;
q = Quantile(0.5,vals);
show(q);
En règle générale, j’utiliserais Wait (0) si je voulais assurer la synchronisation - cela ne concerne normalement que les problèmes de type d’E / S. Il n'y a que de rares cas où Wait ne fonctionne pas - et c'est parce que l'exécution s'exécute dans un thread séparé.
Re: mode de synchronisation?Il est beaucoup plus facile de diagnostiquer si vous pouvez fournir un exemple de code reproduisant le problème que nous pouvons exécuter. Sans cela, j'ai écrit ma propre version. Il contient tout votre code mais j'ai fourni la table source et destination (sumdt). La seule différence est que vous avez la notation thisCol [], ce qui implique que vous utilisez une boucle For Each Row. Je ne comprenais pas le contexte, j'ai donc simplement utilisé une boucle For:
dt = Open("$SAMPLE_DATA/Big Class.jmp");
colList = dt << Get Column Names(string,numeric);
N = NItems(colList);
sumdt = new table("sumdt",
Add Rows(N),
new column("name", character),
new column("Q10"),
new column("Q25"),
new column("Q50"),
new column("Q75"),
new column("Q90"),
);
selRows = dt << Get Rows Where(:sex=="F");
For (i=1,i<=N,i++,
thisName = colList[i];
Column(sumdt,"name")[i] = thisName;
thisCol = Column(sumdt, "Q10");
valueSet = Column(dt, colList[i])[selRows];
thisValue = Quantile(0.10, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q25");
thisValue = Quantile (0.25, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q50");
thisValue = Quantile (0.50, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q75");
thisValue = Quantile (0.75, valueSet);
thisCol[i] = thisValue;
thisCol = Column(sumdt, "Q90");
thisValue = Quantile (0.90, valueSet);
thisCol[i] = thisValue;
);
Ce code fonctionne bien sans aucun problème de synchronisation. Vous voudrez peut-être comparer le code et voir ce qui est différent.
Re: mode de synchronisation?Vous pouvez essayer d'utiliser une boucle. Vous pouvez incorporer une étape dans la boucle qui copie la valeur dans une matrice ou un tableau associatif avant le début de la boucle suivante. Cela ferait probablement en sorte que les choses suivent la cadence souhaitée.
Meilleur,
M