I have a CSV file containing data which I read using a Bean Shell script and populate an ArrayList based upon it.Below is the code for it.
//Populate Beanshell script
import java.text.*;
import java.io.*;
import java.util.*;
ArrayList strList = new ArrayList();
try {
File file = new File("path/to/csv");
if (!file.exists()) {
throw new Exception ("ERROR: file not found");
}
BufferedReader bufRdr = new BufferedReader(new FileReader(file));
String line = null;
while((line = bufRdr.readLine()) != null) {
strList.add(line);
}
bufRdr.close();
}
catch (Exception ex) {
IsSuccess = false;
log.error(ex.getMessage());
System.err.println(ex.getMessage());
}
catch (Throwable thex) {
System.err.println(thex.getMessage());
}
Now I want to utilize this data in a random manner so I am trying to use something like this
//Consumer bean shell script
//Not able to access strList since vars.put cannot store an object
Random rnd = new java.util.Random();
vars.put("TheValue",strList.get(rnd.nextInt(strList.size())));
But I am unable to do this because in vars.put I cannot store an array or a list,I can only store only primitive types.So there is no way in which I can access the populate function's ArrayList from an another BeanShell script.
How do I achieve randomization in this scenario since calling populate function each and every time is not good from a performance point of view.
vars.put only supports String values. There is vars.putObject:
Scripts can also access JMeter variables using the get() and put()
methods of the "vars" variable, for example: vars.get("HOST");
vars.put("MSG","Successful"); . The get() and put() methods only
support variables with String values, but there are also getObject()
and putObject() methods which can be used for arbitrary objects.
JMeter variables are local to a thread, but can be used by all test
elements (not just Beanshell).
I would recommend using bsh.shared namespace, this way you will be able to store any Java object and access it even from different Thread Groups if needed.
JMeter-specific example is in the official documentation, in Sharing Variables chapter
At the end of 1st script:
bsh.shared.strList = strList;
At the beginning of the 2nd script:
List strList = bsh.shared.strList;
Random rnd = new java.util.Random();
vars.put("TheValue",strList.get(rnd.nextInt(strList.size())));
See How to use BeanShell: JMeter's favorite built-in component guide for more details on Beanshell scripting for JMeter.
Hope this will help someone.
For sharing variables globally, i.e. among threads in all thread groups, use props.
For e.g,
In setup thread group, do this
props.put("mylist", new ArrayList());
Now, in post processor for every thread in the thread group, add values to the list.props.get("mylist").add(<some value>);
In tear down thread group, fetch the entire list again.
log.info(props.get("mylist").toString());
In thread group, list is updated by multiple threads then prefer to use Vector instead of ArrayList.
Ref : scope-of-variables-sharing-among-threads-and-thread-groups
Related
public boolean isConnectedTo(Suspect aSuspect){
boolean flag = false;
Registry tempRegistry = new Registry();
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
for(Communication comms : TempComms) {
System.out.println("here");
for(String PhoneNums : phoneNumbers){
if(PhoneNums.equals(comms.GetTransmitter())) {
for(String numbers : aSuspect.getNumbersList()) {
if(numbers.equals(comms.GetReceiver()))
flag = true;
}
}
}
}
return flag;
}
So I am trying to create a program that among other things, it will search two ArrayLists(TempComs and phoneNumbers) and it will return true or false whether a string in the first is the same with a string in the second or not. I create the new ArrayList TempComms with the method tempRegistry.GetComms(). GetComms() is a method in another class, (class Registry) and has just a return communications; command, communications is an ArrayList in the class Registry.(The ArrayList phoneNumbers is an arrayList of the class the code is into.) So normally with with
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
the ArrayList TempComms must be the same with ArrayList communication that exists in the other class. But I figured out that for some reason the problem is in TempComms, because the first for is never running(For that reason I used System.out.println("here"); but it never printed). I searched and tried a lot to find the solution of this problem of my own, but I didn't manage to make some progress, so I would be grateful if someone who knows where's the problem or what I do wrong tell me about it. Thanks anyway.
You are creating a new instance of the Registry which contains a list (comms).
Registry tempRegistry = new Registry();
Then you are trying to get that comm list by calling tempRegistry.GetComms() .
Unless you are populating this communication list in the constructor Registry() (not only instantiating, you should add some entries as well),
that list will be empty when for loop is called.
(Because you are clearly NOT populating it after creating the instance tempRegistry and before calling the for loop.
ArrayList<Communication> TempComms = new ArrayList<Communication>(tempRegistry.GetComms());
for(Communication comms : TempComms) {
Therefore, the TempComms list is also an empty list. Which is why the inside code of the for loop is not executing.
My original tree was much bigger, but since I'm stuck with this issue for quite some time I decided to try to simplify my tree. I Ended up with something like this:
As you can see, I only have a single attribute called "LarguraBandaRede" with 3 possible nominal values "Congestionado", "Livre" and "Merda".
After that I exported the j48.model from weka to use on my java code.
With this piece of code I import the model to use as a classifier:
ObjectInputStream objectInputStream = new ObjectInputStream(in);
classifier = (J48) objectInputStream.readObject();
After that I started to create a arraylist of my attributes and a Instances File
for (int i = 0; i <features.length; i++) {
String feature = features[i];
Attribute attribute;
if (feature.equals("TamanhoDados(Kb)")) {
attribute = new Attribute(feature);
} else {
String[] strings = null;
if(i==0) strings = populateAttributes(7);
if(i==1) strings = populateAttributes(10);
ArrayList<String> attValues = new ArrayList<String>(Arrays.asList(strings));
attribute = new Attribute(feature,attValues);
}
atts.add(attribute);
}
where populateAttributes gives the possible values for each attribute, in this case "Livre, Merda, Congestionado;" for LarguraBandaRede and "Sim,Nao" for Resultado, my class attribute.
Instances instances = new Instances("header",atts,atts.size());
instances.setClassIndex(instances.numAttributes()-1);
After creating my instances is time to create my Instance File, that is, the instances that I'm trying to classify
Instance instanceLivre = new DenseInstance(features.length);
Instance instanceMediano = new DenseInstance(features.length);
Instance instanceCongestionado = new DenseInstance(features.length);
instanceLivre.setDataset(instances);
instanceMediano.setDataset(instances);
instanceCongestionado.setDataset(instances);
then I set each of this instances with the 3 possible values for "LarguraBandaRede". 'instanceLivre' with "Livre", 'instanceMediano' with "Merda" and 'instanceCongestionado' with "Congestionado".
After that I only classify this 3 instances using the classifyInstance method
System.out.println(instance.toString());
double resp = classifier.classifyInstance(instance);
System.out.println("valor: "+resp);
and this is my result:
As you can see, the instance that has Merda as "LarguraBandaRede" was classify to be the same class as Congestionado, the class 'Nao'. But that doesn't make any sense, since the tree above clearly show that when "LarguraBandaRede" is "Merda" or "Livre" the class should be the same.
So that's my question. How this happened and how to fix it?
Thanks in advance.
EDIT
I didn't know that this:
made any difference in the way the model works. But we have to follow this order when feeding a nominal attribute with possible values.
Have you checked if the weka nominal attribute index is equal in order to your populateAttributes method?
I am using JHDF5 to log a collection of values to a hdf5 file. I am currently using two ArrayLists to do this, one with the values and one with the names of the values.
ArrayList<String> valueList = new ArrayList<String>();
ArrayList<String> nameList = new ArrayList<String>();
valueList.add("Value1");
valueList.add("Value2");
nameList.add("Name1");
nameList.add("Name2");
IHDF5Writer writer = HDF5Factory.configure("My_Log").keepDataSetsIfTheyExist().writer();
HDF5CompoundType<List<?>> type = writer.compound().getInferredType("", nameList, valueList);
writer.compound().write("log1", type, valueList);
writer.close();
This will log the values in the correct way to the file My_Log and in the dataset "log1". However, this example always overwrites the previous log of the values in the dataset "log1". I want to be able to log to the same dataset everytime, adding the latest log to the next line/index of the dataset. For example, if I were to change the value of "Name2" to "Value3" and log the values, and then change "Name1" to "Value4" and "Name2" to "Value5" and log the values, the dataset should look like this:
I thought the keepDataSetsIfTheyExist() option to would prevent the dataset to be overwritten, but apparently it doesn't work that way.
Something similar to what I want can be achieved in some cases with writer.compound().writeArrayBlock(), and specify by what index the array block shall be written. However, this solution doesn't seem to be compatible with my current code, where I have to use lists for handling my data.
Is there some option to achieve this that I have overlooked, or can't this be done with JHDF5?
I don't think that will work. It is not quite clear to me, but I believe the getInferredType() you are using is creating a data set with 2 name -> value entries. So it is effectively creating an object inside the hdf5. The best solution I could come up with was to read the previous values add them to the valueList before outputting:
ArrayList<String> valueList = new ArrayList<>();
valueList.add("Value1");
valueList.add("Value2");
try (IHDF5Reader reader = HDF5Factory.configure("My_Log.h5").reader()) {
String[] previous = reader.string().readArray("log1");
for (int i = 0; i < previous.length; i++) {
valueList.add(i, previous[i]);
}
} catch (HDF5FileNotFoundException ex) {
// Nothing to do here.
}
MDArray<String> values = new MDArray<>(String.class, new long[]{valueList.size()});
for (int i = 0; i < valueList.size(); i++) {
values.set(valueList.get(i), i);
}
try (IHDF5Writer writer = HDF5Factory.configure("My_Log.h5").writer()) {
writer.string().writeMDArray("log1", values);
}
If you call this code a second time with "Value3" and "Value4" instead, you will get 4 values. This sort of solution might become unpleasant if you start to have hierarchies of datasets however.
To solve your issue, you need to define the dataset log1 as extendible so that it can store an unknown number of log entries (that are generated over time) and write these using a point or hyperslab selection (otherwise, the dataset will be overwritten).
If you are not bound to a specific technology to handle HDF5 files, you may wish to give a look at HDFql which is an high-level language to manage HDF5 files easily. A possible solution for your use-case using HDFql (in Java) is:
public class Example
{
public Class Log
{
String name1;
String name2;
}
public boolean doSomething(Log log)
{
log.name1 = "Value1";
log.name2 = "Value2";
return true;
}
public static void main(String args[])
{
// declare variables
Log log = new Log();
int variableNumber;
// create an HDF5 file named 'My_Log.h5' and use (i.e. open) it
HDFql.execute("CREATE AND USE FILE My_Log.h5");
// create an extendible HDF5 dataset named 'log1' of data type compound
HDFql.execute("CREATE DATASET log1 AS COMPOUND(name1 AS VARCHAR, name2 AS VARCHAR)(0 TO UNLIMITED)");
// register variable 'log' for subsequent usage (by HDFql)
variableNumber = HDFql.variableRegister(log);
// call function 'doSomething' that does something and populates variable 'log' with an entry
while(doSomething(log))
{
// alter (i.e. extend) dataset 'log1' to +1 (i.e. add a new row)
HDFql.execute("ALTER DIMENSION log1 TO +1");
// insert (i.e. write) data stored in variable 'log' into dataset 'log1' using a point selection
HDFql.execute("INSERT INTO log1(-1) VALUES FROM MEMORY " + variableNumber);
}
}
}
this is my first post here. I have recently started to get interested in learning Java, I have read through some beginner level tutorials, kept http://docs.oracle.com as my bookmark and read several sample codes.
Now messing with my own for practice I discovered something weird for which I couldn't find any satisfying answer in manuals/tutorials/documentation.
Theres a little class I produced to practice IO, and queue style objects. It is meant to create an object containing file name, and an empty linkedlist. Then it has a method for that given file to be read and lines from that added one by one to the linkedlist queue.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.LinkedList;
public class Handle
{
public File filehandle;
public LinkedList<String> queue;
Handle (File filename)
{
filehandle=filename;
LinkedList<String> queue = new LinkedList<String>();
}
public void addq()
{
try{
FileReader ava;
ava = new FileReader(filehandle);
//without initializing new linekedlist queue it'll give NPE in queue.add
//why can't it use class/instance variable queue it does fine with filehandle
queue = new LinkedList<String>();
BufferedReader br = null;
String sCurrentLine;
br = new BufferedReader(ava);
while ((sCurrentLine = br.readLine()) != null)
{
queue.add(sCurrentLine);
}
queue.offer("POISON");
}
catch (IOException e) {e.printStackTrace();}
}
The weird thing - When tried to use class variable/instance variable queue (public LinkedList queue) declared in class, the one also initiated in constructor, inside the method, it compiled fine but at the runtime it threw NPE at queue.add lines. NPE faded as I initialized method variable queue inside method. Why can't the method add to class variable queue? It seems to use the fielhandle variable just fine!
Also as shown by the poll method result in code running the class(posting it down) - it still seems to actually add the lines into the instance variable queue not just temporary method variable. (Which is of course good but I do not understand how and why)
Down here is the code that I used to run the Handle class in.
import java.io.File;
import java.util.LinkedList;
class Runner
{
public static void main(String[] args)
{
File file = new File("proovidest.csv");
Handle handle =new Handle(file);
//using the constructor, now we have object with filehandle and empty queue variables
handle.addq();
String mison;
//so apparently the instance variable queue is still filled with lines (good)
//but how? the method had to delcare its own variable (why), but still the class field is //now filled? how?
while ((mison = handle.queue.poll()) != "POISON")
{System.out.println(mison);}
}
}
So can anybody give me good explanation why I couldn't acess the class variable queue in method in runtime, although I was able to use filehandle variable.
What SHOULD I do to access it then?
Can anybody tell me how the class field queue then still got filled, although I declared a new variable inside the method. Or does the handle.queue.poll somehow detect variables form methods?
The problem is here:
Handle (File filename) {
filehandle=filename;
LinkedList<String> queue = new LinkedList<String>();
}
You don't initialize the instance field queue, rather you create a new local variable with the same name, which is valid only in the constructor. Change it to:
Handle (File filename) {
filehandle=filename;
queue = new LinkedList<String>();
}
and it should not throw a NPE.
Inside your constructor, you declared a local variable queue, hiding your class variable!
Handle (File filename)
{
filehandle=filename;
this.queue = new LinkedList<String>();
}
The problem is the visibility of your LinkedList. It is only visible in your private constructor. To use the queue LinkedList just write this in your constructor:
queue = new LinkedList<String>();
furthermore remove that in addq:
queue = new LinkedList<String>();
Looks there is no place to fire NPE on your code.
It will fire File not found exception if mention file not in location.
Can you post stack trace to more investigations.
Okay, I'm sure that I'm not going about this in the most efficient way and I'm looking for some help regarding how to do this more efficiently...
config.txt file contains key/value pairs, where key = name of test and value = whether to execute test
parse through config file and create a list of tests to run
run those tests
Here is how I'm currently going about this
create an ArrayList by passing to a helper function, parseConfig, a BufferedReader over my config file. parseConfig returns a TreeSet , which I use in the constructor method for my ArrayList
parseConfig iterates over lines of text in config file. If value indicates to perform test, add name of test to TreeSet. Return TreeSet.
Iterate over ArrayList with enhanced for loop. Body of enhanced for loop is basically a long if/else statement...if key.equals ("thisTest"), perform thisTest, else if key.equals (thatTest), perform thatTest...etc
It's that last part that I really don't like. It works well enough, but it seems clumsy and inefficient. Since my ArrayList is constructed using a TreeSet, it is in sorted order. I would like to use a more elegant and deterministic method for mapping my keys to tests to perform. Can anyone help me?
I would do something else since all you need to do with this list is to test it's entries or not.
I would take line by line and apply a regular expression on it, from what I see it is going to be really simple with only two groups and a positive lookahead, this way I could extract all the matching lines only and create an ArrayList out of those, then iterate the ArrayList and test every method. If you can give some input of how the file looks I can help you put with the code.
UPDATE
For example here is the code I come up (in 5 min could be improved) that would do the parsing:
/**
*
* #param inputFile location of inputFile
* #return {#link ImmutableSet} of tests to run
*/
public static ImmutableSet<String> parseConfigFile(File inputFile){
HashSet<String> innerSet = Sets.newHashSet();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(inputFile));
String newLine = "";
while( (newLine = bufferedReader.readLine()) != null){
Pattern p = Pattern.compile("(.+)=(?=yes|1|true)(.+)");
Matcher m = p.matcher(newLine);
while(m.find()){
//System.out.println(m.group(1));
innerSet.add(m.group(1));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedReader != null)
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ImmutableSet.copyOf(innerSet);
}
I testes it for a file that looks like this for example:
SomeTest=true
SomeOtherTest=false
YetAnotherTest=1
LastTest=yes
GogoTest=no
OneMore=0
The answer was to create a HashMap <String, Method> object.