ListOfFiles, getPath, shuffling when have more than 3 - java

im using this to display a image in a certain folder and subfolder, everything "works fine", the files are named in this form ex:
17000.001
17000.002
18555.001
18542.001
1.001
1.002
1.003
1.004
.....
the .xxx is the extension (a renamed TIFF)
the program works in this way:
You Type the Number you want, example: i want the 17000, i type 17000, and it return the FIRST .001 in the screen, and the others .002, .003 and how many it have, i want to walk throught it by a next image button and previsoly image...
the problem is: when i try to search for a number that have more than 4 .004 or more, it dont display the first, it display "random", .002, 004 or other i cant understand why, this is the piece of the code where i get the "path" to it!! dont kill me because the code ^^!
....
public void geraListaArquivos(String subdir, String matricula) {
String diretorio = "F:\\registro_sql\\Imagens\\Livro02" + "\\"
+ subdir + "\\";
String novaimagem = null;
File folder = new File(diretorio);
listOfFiles = folder.listFiles();
if (!folder.exists()) {
JOptionPane.showMessageDialog(null,"Não existe o diretório em que está tentando fazer a busca");
} else {
// JOptionPane.showMessageDialog(null, diretorio);
for (int i = 0; i < listOfFiles.length; i++) {
String matsonome[] = listOfFiles[i].getName().split("\\.");
for (int i2 = 0; i2 < matsonome.length; i2 = i2 +2) {
if(matsonome[i2].matches(matricula)) {
System.out.println(matsonome[i2] = "." + matsonome[i2+1]);
... the rest of the code, if the typed number image exist in the folder
i dit the String matsonome to check if the first part of the array matches the typed number,.. i2 +2, coz wwhen it split for example 17000.001 and 17000.002
will be in this way:
matsonome[0] = 17000
matsonome[1] = 001
matsonome[2] = 17000
matsonome[3] = 002
in this case the "System.out.println(matsonome[i2] = "." + matsonome[i2+1]);"
will display correct cuz it have less than 4
17000.001
17000.002
but if the typed number have 4 or more, it display in this way(out of order):
xxxx.002
xxxx.001
xxxx.004
xxxx.003
why???
sorry the bad english :(

I believe it's because the order isn't guaranteed (if I correctly understand the question).
See the documentation:
There is no guarantee that the name strings in the resulting array
will appear in any specific order; they are not, in particular,
guaranteed to appear in alphabetical order.
That means you'll have to sort the array using a static function.

Related

How to convert double values to string in a text field

I want to do the average of 9 textfields and also the sum of them and place them in 2 other textfields by using a button, currently this code doesnt displays anything in the other textfiels. If i put anything, for example "A" instead of "%.Of" it would display the "A" in the textfield but not the average or the sum. Please i need help with a code that would work, dont mind if i need to change a lot.
This is what im working with:
private void jButton_RankingActionPerformed(java.awt.event.ActionEvent evt) {
double R[] = new double [14];
R[0] = Double.parseDouble(jTextField_Math.getText());
R[1]= Double.parseDouble(jTextField_English.getText());
R[2] = Double.parseDouble(jTextField_Spanish.getText());
R[3] = Double.parseDouble(jTextField_Biology.getText());
R[4] = Double.parseDouble(jTextField_Physics.getText());
R[5] = Double.parseDouble(jTextField_Chemestry.getText());
R[6] = Double.parseDouble(jTextField_PE.getText());
R[7] = Double.parseDouble(jTextField_Humanities.getText());
R[8] = Double.parseDouble(jTextField_Technology.getText());
R[9] = (R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8])/ 9;
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
String Average = String.format("%.Of",R[9]);
jTextField_Average.setText(Average);
String TotalScore = String.format("%.Of",R[10]);
jTextField_TotalScore.setText(TotalScore);
if(R[10]>=50)
{
jTextField_Ranking.setText("Superior");
}
else if (R[10]>=41){
jTextField_Ranking.setText("Alto");
}
else if (R[10]>=34){
jTextField_Ranking.setText("Basico");
}
else if (R[10]<=33){
jTextField_Ranking.setText("Bajo");
Since you mentioned that an A would print, it follows that jButton_RankingActionPerformed is being called. The issue you have is the format string you are using to print the total and average. You have mistakenly chosen the capital letter O rather than the number zero.
Replace this (which contains a capital letter O):
String.format("%.Of",R[9]);
With
1) No decimal will be printed: i.e. 50.2 would be 50
String.format("%.0f",R[9]);
2) Or perhaps you want to see one decimal place like 50.2
String.format("%.1f",R[9]);
Also a very small optimization is:
R[9] = (R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8])/ 9;
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
Could be replaced with:
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
R[9] = R[10] / 9;
or use a loop to calculate R[10]. (to add R[0] to R[8])

checking if my array elements meet requirements

I need to create a method which checks each element in my array to see if it is true or false, each element holds several values such as mass, formula, area etc for one compound, and in total there are 30 compounds (so the array has 30 elements). I need an algorithm to ask if mass < 50 and area > 5 = true .
My properties class looks like:
public void addProperty (Properties pro )
{
if (listSize >=listlength)
{
listlength = 2 * listlength;
TheProperties [] newList = new TheProperties [listlength];
System.arraycopy (proList, 0, newList, 0, proList.length);
proList = newList;
}
//add new property object in the next position
proList[listSize] = pro;
listSize++;
}
public int getSize()
{
return listSize;
}
//returns properties at a paticular position in list numbered from 0
public TheProperties getProperties (int pos)
{
return proList[pos];
}
}
and after using my getters/setters from TheProperties I put all the information in the array using the following;
TheProperties tp = new properties();
string i = tp.getMass();
String y = tp.getArea();
//etc
theList.addProperty(tp);
I then used the following to save an output of the file;
StringBuilder builder = new StringBuilder();
for (int i=0; i<theList.getSize(); i++)
{
if(theList.getProperties(i).getFormatted() != null)
{
builder.append(theList.getProperties(i).getFormatted());
builder.append("\n");
}
}
SaveFile sf = new SaveFile(this, builder.toString());
I just cant work out how to interrogate each compound individually for whether they reach the value or not, reading a file in and having a value for each one which then gets saved has worked, and I can write an if statement for the requirements to check against, but how to actually check the elements for each compound match the requirements? I am trying to word this best I can, I am still working on my fairly poor java skills.
Not entirely sure what you are after, I found your description quite hard to understand, but if you want to see if the mass is less than 50 and the area is greater than 5, a simple if statement, like so, will do.
if (tp.getMass() < 50 && tp.getArea() > 5) {}
Although, you will again, have to instantiate tp and ensure it has been given its attributes through some sort of constructor.
Lots of ways to do this, which makes it hard to answer.
You could check at creation time, and just not even add the invalid ones to the list. That would mean you only have to loop once.
If you just want to save the output to the file, and not do anything else, I suggest you combine the reading and writing into one function.
Open up the read and the write file
while(read from file){
check value is ok
write to file
}
close both files
The advantage of doing it this way are:
You only loop through once, not three times, so it is faster
You never have to store the whole list in memory, so you can handle really large files, with thousands of elements.
In case the requirements changes, you can write method that uses Predicate<T>, which is a FunctionalInterface designed for such cases (functionalInterfaces was introduced in Java 8):
// check each element of the list by custom condition (predicate)
public static void checkProperties(TheList list, Predicate<TheProperties> criteria) {
for (int i=0; i < list.getSize(); i++) {
TheProperties tp = list.get(i);
if (!criteria.apply(tp)) {
throw new IllegalArgumentException(
"TheProperty at index " + i + " does not meet the specified criteria");
}
}
}
If you want to check if mass < 50 and area > 5, you would write:
checkProperties(theList, new Predicate<TheProperties> () {
#Override
public boolean apply(TheProperties tp) {
return tp.getMass() < 50 && tp.getArea() > 5;
}
}
This can be shortened by using lambda expression:
checkProperties(theList, (TheProperties tp) -> {
return tp.getMass() < 50 && tp.getArea() > 5;
});

Transforming google maps waypoint directions to via-directions

I am trying to change the URL of google maps directions from directions which have multiple waypoints to directions where these intermediate waypoints are deleted but the route remains the same.
Specifically from: https://www.google.nl/maps/dir/51.804323,5.8061076/51.8059489,5.7971745/51.8095767,5.8032703/#51.8068221,5.806553,16.5z/data=!4m2!4m1!3e2
to:
https://www.google.nl/maps/dir/51.804323,5.8061076/51.8095767,5.8032703/#51.8069622,5.8023697,17z/data=!4m9!4m8!1m5!3m4!1m2!1d5.7971218!2d51.8060231!3s0x47c7061292e15b39:0x4d7bcd7484c71cf3!1m0!3e2
EDIT: because I had to drag the route manually in the second URL the coordinates of the middle marker are not exactly the same as in the first URL; this difference can be ignored.
the start part of these URLS seem pretty obvious as to what they are doing, however the data parameter is still unclear to me (without it the route is not correct). I tried the Google Maps API, but these return an XML or JSON file, but I just need the corresponding URL which I would also get using the webinterface of Google Maps.
How can I tranform the first URL to the second??
So after a long time trying to figure out how the URL scheme works, I finally figured out how it works (for the directions interface).
The URL consists of the following steps:
You start off with "https://www.google.nl/maps/dir/"
This is followed by the start coordinates in the form "[LAT],[LONG]", the coordinates of intermediate waypoints in the same format,and then the coordinates of end points. All these coordinates are seperated by a "/" character.
This is followed by "#[LAT],[LONG],[ZOOM]/" where LAT LONG are the coordinates of the viewbox and ZOOM is the level of zoom (lower means more zoomed out).
This is followed by "data=" and then "!4m[(5x+4+y)]!4m[(5x+3+y)]!" where x is the amount of VIA-points and y is the amount of intermediate waypoints in the route. So if you have a route from A to D with intermediate destinations B and C and VIA points Q, W and R you have x=3 and y=2 so you get the string "!4m21!4m20"
Next we get all VIA points. This done in the following scheme: you append "!1m[(5x)]" where x is the amount of VIA-points between the current waypoint and the next. So "!1m5...[data]...!1m0" means that between the start and first waypoint there is one VIA-point and between the first waypoint and the end there are no VIA-points. Each "!1m[(5x)]" is followed by x instances of "!1d[LONG]!2d[LAT]!3s[COORDINATE]". I am not entirely sure what COORDINATE does, but is has to be in the format "0x[HEX]:0x[HEX]" where HEX is a hexadecimal number; I simply take the number 0 for this. This seems to work in all my test cases and does not seem to influence anything.
This is then followed by "!1m0". I believe this is necessary to indicate that after the last waypoint (the finish) there are no more VIA points, which is useless information but needed nevertheless.
Finally, we get the last parameter which looks like "!3e[n]" where n is a discrete variable to indicate the type of navigation: n=0 for driving by car,n=1 is for bicycle riding, n=2 is for walking, and n=3 for public transportation.
That is mostly it for what I found out about the URL scheme by testing it relentlessly. There are more parameters you can add, but that needs more work testing.
Finally, I included my implementation for transforming a URL with 0 or more waypoints and 0 or more VIA-points to a URL containing only VIA-points. Feel free to use it and please let me know if you have found any mistakes so I can fix them.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter URL: ");
String originalURL = br.readLine();
//get start of URL
String start = "https://www.google.nl/maps/dir/";
//get navigation type
String type = "!3e1";
Matcher t = getMatcher(originalURL, "!3e\\d");
if (t.find()) {
type = t.group();
}
//get viewbox parameter
Matcher v = getMatcher(originalURL, "#[-]?[\\d]+\\.[\\d]+,[-]?[\\d]+.[\\d]+,[-]?[\\d]+[[.]+[\\d]+]*z");
v.find();
String viewbox = v.group();
//get order of points when using VIA
String data = originalURL.substring(originalURL.indexOf("/data=") + 6);
ArrayList<String> order = new ArrayList<>();
Matcher o = getMatcher(data, "!1m[\\d]+");
while (o.find()) {
order.add(o.group());
}
if (order.size() > 0) {
//remove the last element which is always m0 as this should not be
//displayed in the VIA-list
order.remove(order.size() - 1);
}
//!1m2 does not represent the order but indicates that coordinates that are coming up
order.removeIf(a -> a.equals("!1m2"));
//get coordinates of via-points
ArrayList<String> originalViaPoints = new ArrayList<>();
Matcher c = getMatcher(data, "!1d[-]?[\\d]+.[\\d]+!2d[-]?[\\d]+.[\\d]+");
while (c.find()) {
String[] g = c.group().substring(3).split("!2d");
originalViaPoints.add(g[1] + "," + g[0]);
}
//get coordinates of start, end and intermediate points
originalURL = originalURL.substring(0, v.start());
ArrayList<String> waypoints = new ArrayList<>();
Matcher p = getMatcher(originalURL, "[-]?[\\d]+\\.[\\d]+,[-]?[\\d]+.[\\d]+");
while (p.find()) {
waypoints.add(p.group());
}
//start and end must be displayed seperately
String bound = waypoints.get(0) + "/" + waypoints.get(waypoints.size() - 1);
//add intermediate waypoints and via-points to a list of VIA points
ArrayList<String> viaPoints = new ArrayList<>();
//we have VIA points to process
if (!order.isEmpty()) {
int via_index = 0;
int wp_index = 1;
for (String step : order) {
int iter = Integer.valueOf(step.substring(3)) / 5;
for (int i = 0; i < iter; i++) {
viaPoints.add(originalViaPoints.get(via_index++));
}
viaPoints.add(waypoints.get(wp_index++));
}
} else //There are only waypoints in the URL
{
for (int i = 1; i < waypoints.size() - 1; i++) {
viaPoints.add(waypoints.get(i));
}
}
//calculate prefix according to the amount of nodes of the via points
int nodes = viaPoints.size();
String prefix = "!4m" + (5 * nodes + 4) + "!4m" + (5 * nodes + 3) + "!1m" + (5 * nodes);
//get nodes string
String viaString = "";
for (String node : viaPoints) {
viaString += "!3m4!1m2";
String[] pieces = node.split(",");
viaString += "!1d" + pieces[1]; //ALERT: the coordinates are flipped!
viaString += "!2d" + pieces[0];
viaString += "!3s0x0:0x0";
}
String url = start + bound + "/" + viewbox + "/data=" + prefix + viaString + "!1m0" + type;
According to this site, in the old url scheme, there should be 3 ways to add a via point or a route, and they are:
https://www.google.com/maps?dirflg=w&saddr=51.804323,5.8061076&daddr=51.8059489,5.7971745+to:51.8095767,5.8032703
https://www.google.com/maps?dirflg=w&saddr=51.804323,5.8061076&daddr=51.8095767,5.8032703&mrad=51.8059489,5.7971745
https://www.google.com/maps?dirflg=w&saddr=51.804323,5.8061076&daddr=51.8095767,5.8032703&via=51.8059489,5.7971745
But it seems they dropped support to mrad and via. And for using to, it shows the address as if it would be shown in the new url scheme.
For the new URL scheme.. it does not seems to have a lot of documentation on it, so I am not sure if Google wants you to play with it. but... here it is: How to do it with the new scheme.
according to this blog post:
the !xx, is a separator. Looking at your url:
data=
!4m9
!4m8
!1m5
!3m4
!1m2
!1d5.7971218
!2d51.8060231
!3s0x47c7061292e15b39:0x4d7bcd7484c71cf3
!1m0
!3e2
it is really unclear what it is doing, but, at least we see your via lat, and via lng in the !1d and !2d fields;
Also the !3s, in a hex format looks like some kind of lat/lng, might be the area of search. This is how it looks like in dec 5172109373901724473:5583282063383403763
Well, in short, just change the !1d and !2d fields and it seems to work fine. like this:
https://www.google.nl/maps/dir/51.804323,5.8061076/51.8095767,5.8032703/#51.8769532,5.8550939,7.58z/data=!4m9!4m8!1m5!3m4!1m2!1d5.871218!2d52.8060231!3s0x47c7061292e15b39:0x4d7bcd7484c71cf3!1m0!3e2

How to train data correctly using libsvm?

I want to use SVM (Support vector machine) in my program, but I could not get the true result.
I want to know that how we must train data for SVM.
What I am doing:
Think that we have 5 document (the numbers are just an example), 3 of them is on first category and others (2 of them) are on second category, I merge the categories to each other (it means that the 3 doc that are in the first category will merge in one document), after that I made a train array like this:
double[][] train = new double[cat1.getDocument().getAttributes().size() + cat2.getDocument().getAttributes().size()][];
and I will fill the array like this:
int i = 0;
Iterator<String> iteraitor = cat1.getDocument().getAttributes().keySet().iterator();
Iterator<String> iteraitor2 = cat2.getDocument().getAttributes().keySet().iterator();
while (i < train.length) {
if (i < cat2.getDocument().getAttributes().size()) {
while (iteraitor2.hasNext()) {
String key = (String) iteraitor2.next();
Long value = cat2.getDocument().getAttributes().get(key);
double[] vals = { 0, value };
train[i] = vals;
i++;
System.out.println(vals[0] + "," + vals[1]);
}
} else {
while (iteraitor.hasNext()) {
String key = (String) iteraitor.next();
Long value = cat1.getDocument().getAttributes().get(key);
double[] vals = { 1, value };
train[i] = vals;
i++;
System.out.println(vals[0] + "," + vals[1]);
}
i++;
}
so I will continue like this to get the model :
svm_problem prob = new svm_problem();
int dataCount = train.length;
prob.y = new double[dataCount];
prob.l = dataCount;
prob.x = new svm_node[dataCount][];
for (int k = 0; k < dataCount; k++) {
double[] features = train[k];
prob.x[k] = new svm_node[features.length - 1];
for (int j = 1; j < features.length; j++) {
svm_node node = new svm_node();
node.index = j;
node.value = features[j];
prob.x[k][j - 1] = node;
}
prob.y[k] = features[0];
}
svm_parameter param = new svm_parameter();
param.probability = 1;
param.gamma = 0.5;
param.nu = 0.5;
param.C = 1;
param.svm_type = svm_parameter.C_SVC;
param.kernel_type = svm_parameter.LINEAR;
param.cache_size = 20000;
param.eps = 0.001;
svm_model model = svm.svm_train(prob, param);
Is this way correct? if not please help me to make it true.
these two answers are true : answer one , answer two,
Even without examining the code one can find conceptual errors:
think that we have 5 document , 3 of them is on first category and others( 2 of them) are on second category , i merge the categories to each other (it means that the 3 doc that are in the first category will merge in one document ) ,after that i made a train array like this
So:
training on the 5 documents won't give any reasonable effects, with any machine learning model... these are statistical models,there is no reasonable statistics in 5 points in R^n, where n~10,000
You do not merge anything. Such approach can work for Naive Bayes, which do not really treat documents as "whole" but rather - as probabilistic dependencies between features and classes. In SVM each document should be separate point in the R^n space, where n can be number of distinct words (for bag of words/set of words representation).
A problem might be that you do not terminate each set of features in a training example with an index of -1 which you should according to the read me...
I.e. if you have one example with two features i think you should do:
Index[0]: 0
Value[0]: 22
Index[1]: 1
Value[1]: 53
Index[2]: -1
Good luck!
Using SVMs to classify text is a common task. You can check out research papers by Joachims [1] regarding SVM text classification.
Basically you have to:
Tokenize your documents
Remove stopwords
Apply stemming technique
Apply feature selection technique (see [2])
Transform your documents using features achieved in 4.) (simple would be binary (0: feature is absent, 1: feature is present) or other measures like TFC)
Train your SVM and be happy :)
[1] T. Joachims: Text Categorization with Support Vector Machines: Learning with Many Relevant Features; Springer: Heidelberg, Germany, 1998, doi:10.1007/BFb0026683.
[2] Y. Yang, J. O. Pedersen: A Comparative Study on Feature Selection in Text Categorization. International Conference on Machine Learning, 1997, 412-420.

Docx4j: Insert item X times after current item under parent

I'm attempting to use DOCX4J to parse and insert content into a template. As part of this template I have loops which I need to copy everything inbetween two markers, and repeat all that content X times.
The relavant code is as follows:
public List<Object> getBetweenLoop(String name){
String startTag = this.tag_start + name + "_LOOP" + this.tag_end;
String endTag = this.tag_start + name + this.tag_end;
P begin_loop = this.getTagParagraph(startTag);
P end_loop = this.getTagParagraph(endTag);
ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);
List<Object> loop = new ArrayList<Object>();
boolean save = false;
//Cycle through the content for the parent and copy all the objects that
//are between and including the start and end-tags
for(Object item : parent.getContent()){
if(item.equals(begin_loop) || item.equals(end_loop))
save = (save) ? false : true;
if(save || item.equals(end_loop)){
loop.add(XmlUtils.deepCopy(item));
}
if(item.equals(end_loop)){
//Here I want to insert everything copied X times after the current item and then exit the for loop.
//This is the part I'm not sure how to do since I don't see any methods "Insert Child", etc.
}
}
return loop;
}
getTagParagraph successfully returns the object representing the paragraph for the tag sent. This works beautifully.
getCommonParent returns the shared parent between the two supplied tags. This works beautifully.
My problem is, as commented, how to insert the newly copied items into the appropriate place.
If you're looking to insert all the objects you have stored in your loop collection, you simply need to do something like this (in the conditional you've commented):
item.getContent().addAll(loop);
item represents the end_loop object (a paragraph or whatever), and inserts all the objects you've collected into the loop collection. (addAll may require an int argument too, I can't recall, but if it does that's just the desired index within the overall MainDocumentPart.getContent() JAXB document representation).
#Ben, thank-you!
If you know of any instances where below wouldn't work, please let me know.
I had actually just figured out something very similar, but ended up changing a lot more code. Below is what I put together.
public void repeatLoop(String startTag, String endTag, Integer iterations){
P begin_loop = this.getTagParagraph(startTag);
P end_loop = this.getTagParagraph(endTag);
ContentAccessor parent = (ContentAccessor) this.getCommonParent(begin_loop, end_loop);
List<Object> content = parent.getContent();
Integer begin_pointer = content.indexOf(begin_loop);
Integer end_pointer = content.indexOf(end_loop);
List<Object> loop = new ArrayList<Object>();
for(int x=begin_pointer; x <= end_pointer; x = x + 1){
loop.add(XmlUtils.deepCopy(content.get(x)));
}
Integer insert = end_pointer + 1;
for(int z = 1; z < iterations; z = z + 1){
content.addAll(insert, loop);
insert = insert + loop.size();
}
}

Categories