I am having a problem with what should be an extremely easy task. I have a very large program that stretches across 10-15 classes. The entire program centers around a Buffered Reader/Writer with a GUI. The users input determines how a file is read and then converted.
Anyway, currently I set the file location with this line.
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+"\\NachaOutput.ACH"));
As you can see I used a constant file name. Some of the data analysts have asked me to make the name dynamic, so I am trying to add a random number. This is how I added the random number:
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
String randomNumber = Integer.toString(newNum);
String location = "//"+randomNumber+"NachaOutput.ACH";
bw = new BufferedWriter(new FileWriter(NachaMain.saveFile.getSelectedFile()+location));
So far so good. When I test the "location" string at this stage it works perfectly. The problem lies in that I must call this file again for buffered readers in two different classes. I have a "FileValidation" class that takes the completed buffered writer file and analyzes it for errors. I attempted to call this "location" variable by making it static like this:
public static String location;
I attempt to call it in the validation class like this:
br = new BufferedReader(new FileReader(NachaMain.saveFile.getSelectedFile()+MainWriter.location));
The file location and everything is correct the problem is that in testing the "location" variable comes up null.
I do not understand this. I set the variable as a static in my "NachaMain" class and then changed it using a random number. Why then is the other class coming up null even though it's accessing a static variable that has already been changed?
If anyone has a solution I would appreciate it. Sorry I can't post more code but I can't see an easy way to isolate this code and there is too much to post my entire program.
Duplicate Notes: This question has been flagged as a duplicate. However the duplicate question was simply describing how to initialize a variable and my answer was much simpler, the problem with naming a variable with it's type declaration twice. I did not find a solution in that post however I got my answer here.
First off - your random looks strange:
// Last I checked, 99-1 + 1 was 99 ;-)
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
String randomNumber = Integer.toString(newNum);
Why not simply
String randomNumber = Integer.toString(new Random().nextInt(100)+1);
But then to your main problem:
String location = "//"+randomNumber+"NachaOutput.ACH";
That's an assignment to a local variable not to a static instance variable
Change it to
location = "//"+randomNumber+"NachaOutput.ACH";
this way, it accesses to static member of the same name. And you have to would have to make sure that location does not change "suddenly". Maybe once per program run is enough? Then add a nullcheck:
if(null == location) {
location = "//"+randomNumber+"NachaOutput.ACH";
}
Advice on things not asked
If I told a developer to make the name "dynamic", I'd expect a program, where I could somehow define the name that's stored.
Ways to do that (some, not all)
Use a System.property for the filename with default
if(null == location) {
location = "//"+System.getProperty("nacha.file", "NachaOutput.ACH");
}
Use a setting that can be changed in the UI. Like a menu "Settings". And then persist choice made in a Preferences
You are trying to assign a value to the static field location by declaring its type:
String location = "//"+randomNumber+"NachaOutput.ACH";
This is likely within a method, and likely gives the location variable method-scope.
In turn, your static String location is never assigned, thus it's null (default String value).
Just remove the type String before declaration, to assign your static field instead.
Unrelated, but worth noting...
The idiom:
int newNum = 1 + (int)(Math.random() * ((99 - 1) + 1));
... only generates pseudo-randoms, and doesn't leverage java.util.Random#next....
I would look into the java.util.UUID.randomUUID() idiom, or java.util.Random#next... just in case.
Related
I dont know how well I'll be able to ask this question, but given a text file I need to parse through and extract the productID data and store it in a HashSet, userID data and store it in a HashSet, and the review/score and store it in an ArrayList. They also need to be used to create a graph, where the productID is connected with an edge between the userID.
The data is found here http://snap.stanford.edu/data/web-FineFoods.html
You can ignore review/time, review/helpfulness, review/summary, and review/text information, they dont need to be stored in memory.
My current code looks like this:
import java.io.*;
import java.util.*;
import java.nio.charset.*;
public class Reviews
{
String fileName = "newfinefoods.txt";
GraphType<String> foodReview;
HashSet<String> productID;
HashSet<String> userID;
ArrayList<String> review;
int counter; //was using this to make sure I'm counting all the lines which I think I am
public Reviews(){
foodReview = new GraphType<>();
productID = new HashSet<>();
userID = new HashSet<>();
review = new ArrayList<>();
counter = 0;
}
public int numReviews(){
return review.size();
}
public int numProducts(){
return productID.size();
}
public int numUsers(){
return userID.size();
}
public void setupGraph(){
Scanner fileScanner;
String line = "";
try{
fileScanner = new Scanner (new File (fileName), "UTF-8");
String pr = "";
while(fileScanner.hasNextLine()){
line = fileScanner.nextLine();
String[] reviewInfo = line.split(": ");
String productInfo = reviewInfo[1];
System.out.println(productInfo);
}
}
catch (IOException e){
System.out.println(e);
}
}
public static void main(String[] args){
Reviews review = new Reviews();
review.setupGraph();
System.out.println("Number of Reviews:" + review.numReviews());
System.out.println("Number of Products:" + review.numProducts());
System.out.println("Number of Users:" + review.numUsers());
}
}
Whenever I run the code, looking in the array reviewInfo at 1, it only prints one set of data, but if I change it to 0 it seems to print all the information (just not the info that I need). I need to create this graph and get the info from the data but I am really just super stuck, and any tips or help would be very appreciated!
Here is a sample of the data:
product/productId: B001E4KFG0
review/userId: A3SGXH7AUHU8GW
review/profileName: delmartian
review/helpfulness: 1/1
review/score: 5.0
review/time: 1303862400
review/summary: Good Quality Dog Food
review/text: I have bought several of the Vitality canned dog food products and have found them all to be of good quality. The product looks more like a stew than a processed meat and it smells better. My Labrador is finicky and she appreciates this product better than most.
product/productId: B00813GRG4
review/userId: A1D87F6ZCVE5NK
review/profileName: dll pa
review/helpfulness: 0/0
review/score: 1.0
review/time: 1346976000
review/summary: Not as Advertised
review/text: Product arrived labeled as Jumbo Salted Peanuts...the peanuts were actually small sized unsalted. Not sure if this was an error or if the vendor intended to represent the product as "Jumbo".
product/productId: B000LQOCH0
review/userId: ABXLMWJIXXAIN
review/profileName: Natalia Corres "Natalia Corres"
review/helpfulness: 1/1
review/score: 4.0
review/time: 1219017600
review/summary: "Delight" says it all
review/text: This is a confection that has been around a few centuries. It is a light, pillowy citrus gelatin with nuts - in this case Filberts. And it is cut into tiny squares and then liberally coated with powdered sugar. And it is a tiny mouthful of heaven. Not too chewy, and very flavorful. I highly recommend this yummy treat. If you are familiar with the story of C.S. Lewis' "The Lion, The Witch, and The Wardrobe" - this is the treat that seduces Edmund into selling out his Brother and Sisters to the Witch.
product/productId: B000UA0QIQ
Initial approach of your design is right, but you should structure it a little more:
Method setupGraph should be splitted in little specific and parametrized methods:
Since the users and products are part of the class' state, I deem it better that the class' constructor receives the scanner as an input parameter. Then, after initializing the state variables, it should call setupGraph (which should be private) passing the input scanner.
setupGraph shall receive an input scanner and take the responsibility of reading lines from it, and give a proper treatment to the IOExceptions that might arise. On each line, it should merely call another private method for processing the read line. If you want to count all the read lines, this is where you should place the increment.
The processing line method shall receive an input string, and take the responsibility of deciding if it contains a product data, a user data, a score data, or none. This must be done through properly parsing its contents.
Here is where you can use String.split() to get the name and value of each line, and then evaluate the name to decide where to store the value. And if you want to count all the processed lines, this is where you should place the increment.
Last, main method shall take the responsability of instancing the scanner and passing it when constructing the Reviews object. In this way, you could receive the file name as input argument from the command line, so your program would become flexible.
Realise that the only public methods of your class should be the constructor and the getters. And state variables shuld be private.
This question already has an answer here:
Beginner Java: Variable Scope Issue
(1 answer)
Closed 7 years ago.
I'm new to programming and seem to be running into issues with when a variable, class, etc can and can't be referenced. Below is an example, hoping one of you can fix the specific issue but also help me understand it more broadly so I don't run into it again and again.
to try and avoid posting a bunch of code please note that a Question class is defined as well as a setText, setAnswer, checkAnswer, and display method are all defined elsewhere (all public).
The relevant code is below and I have two questions:
Why is the variable first not recognized in the method presentQuestion()?
At the very end there, why can't I just call the method checkAnswer() on first, i.e. why can't I just do first.checkAnswer(response);? Why do I have to define it in a new variable: boolean outcome = first.checkAnswer(response);?
Code:
/**
* This program shows a simple quiz with two questions.
*/
public class QuestionDemo {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Question first = new Question();
first.setText("Who was the inventor of Java?");
first.setAnswer("James Gosling");
Question second = new Question();
second.setText("Who was the founder of Udacity?");
second.setAnswer("Sebastian Thrun");
int score = 0;
score = score + presentQuestion(first, in);
// Present the second question
score = score + presentQuestion(second, in);
System.out.println("Your score: " + score);
}
/**
* Presents a question to the user and obtains a response.
* #param q the question to present
* #param in the scanner from which to read the user input
* #return the score (1 if correct, 0 if incorrect);
*/
public static int presentQuestion(Question q, Scanner in) {
// Display the first question
first.display();
System.out.println("Your answer:");
String response = in.nextLine();
// Check whether the response was correct
// If so, print "true" and return 1
// Otherwise, print "false" and return 0
boolean outcome = first.checkAnswer(response);
System.out.println(outcome);
if (outcome) {
return 1;
}
else {
return 0;
}
}
}
The reason you can't use the variable first inside presentQuestion is because it's defined in main, and therefore not visible outside of main. Isn't this precisely why you gave presentQuestion its Question q parameter, however?
It seems to me that this is what you want to do:
public static int presentQuestion(Question q, Scanner in)
{
// Display the first question
q.display();
System.out.println("Your answer:");
String response = in.nextLine();
// Check whether the response was correct
// If so, print "true" and return 1
// Otherwise, print "false" and return 0
boolean outcome = q.checkAnswer(response);
System.out.println(outcome);
if (outcome) {
return 1;
} else {
return 0;
}
}
Note that references to first have been replaced by references to q.
To try and clear up what I imagine your confusion may consist in, imagine if presentQuestion were called from another method than main, in which case no first variable would be declared at all. What would then happen to the references to first inside of presentQuestion, now not referring to anything at all? This is why you need to explicitly pass the data you want as parameters. Different methods are independent blocks of code, and you can't intermingle variable references between them even if they happen to call each other.
As for question 2, there should indeed be no problem with checking if(q.checkAnswer(response)) directly, without using the outcome variable. I'm guessing you were simply confused by the error emitted by the compiler when first wasn't recognized again.
first is a local variable, that means it can only be accessed inside the method in which it is defined.
You don't have to put the result of checkAnswer() into a boolean before using it. Actually, if (checkAnswer(response)) { ... } is valid.
presentQuestion takes a question as a parameter. In main, you're calling it on the first question, and then on the second question; it looks like the intent is that you use presentQuestion on the first question, and then on the second question. So far, so good.
The problem is that in presentQuestion, you're referring to the question (which could be the first or the second question) as q in the parameter list. All you need to do is use q instead of first in the rest of the method.
When I was new to programming, I had this problem as well! Then I found out it is very simple.
For your first question, first is declared in the main method and you want to use it in presentQuestion method. But presentQuestion and main are different methods! So you can't get to first in presentQuestion. As you can see, there is a Question-typed parameter in the presentQuestion method. This is like you telling first, "Come here, man! And then change your name to q." When you do pass the argument first to presentQuestion,
presentQuestion (first, in);
first comes to the pressentQuestion method with its name being as q. So you should use q instead of first in the presentQuestion method.
Now the second question, using a variable in this context is not needed. But to increase efficiency, use a boolean variable to store the result of checkAnswer. Let's imagine what happens if you don't use a boolean variable.
System.out.println(q.checkAnswer(response));
if (q.checkAnswer(response)) {
return 1;
} else {
return 0;
}
See? you called q.checkAnswer twice! This would slow down your program so you should use a boolean variable.
The following requisites are those for the program I'm currently having an issue with:
The program must be able to open any text file specified by the user, and analyze the frequency of verbal ticks in the text. Since there are many different kinds of verbal ticks (such as "like", "uh", "um", "you know", etc) the program must ask the user what ticks to look for. A user can enter multiple ticks, separated by commas.
The program should output:
the total number of tics found in the text
the density of tics (proportion of all words in the text that are tics)
the frequency of each of the verbal tics
the percentage that each tic represents out of all the total number of tics
Here is my program:
public class TextfileHW2 {
// initiate(
public static int[] initiate(int[] values){
for (int z=0; z<keys.length; z++){
values[z] = 0;
}
return values;
processing(values);
}
// processing(values)
public static int[] processing(int[] valuez){
while (input.hasNext()){
String next = input.next();
totalwords++;
for (int x = 0; x<keys.length; x++){
if (next.toLowerCase().equals(keys[x])){
valuez[x]+=1;
}
}
return valuez;
output();
}
for (Integer u : valuez){
totalticks += u;
}
}
public static void output(){
System.out.println("Total number of tics :"+totalticks);
System.out.printf("Density of tics (in percent): %.2f \n", ((totalticks/totalwords)*100));
System.out.println(".........Tick Breakdown.......");
for (int z = 0; z<keys.length; z++){
System.out.println(keys[z] + " / "+ values[z]+" occurences /" + (values[z]*100/totalticks) + "% of all tics");
}
sc.close();
input.close();
}
public static void main(String[] args) throws FileNotFoundException {
static double totalwords = 0; // double so density (totalwords/totalticks) returned can be double
static int totalticks = 0;
System.out.println("What file would you like to open?");
static Scanner sc = new Scanner(System.in);
static String files = sc.nextLine();
static Scanner input = new Scanner(new File(files));
System.out.println("What words would you like to search for? (please separate with a comma)");
static String ticks = sc.nextLine(), tics = ticks.toLowerCase();
static String[] keys = tics.split(",");
static int[] values = new int[keys.length];
initiate(values);
}
My program should be logically right as I wrote it and successfully ran it for a while last week, but the difference with this one (which doesn't work) is that I must use separate methods for each component of the analysis, which shouldn't be too difficult a task considering the program was working before So I naturally tried to split up my program such that I can call my first method (which I called initiate) then my 2nd and 3rd methods called processing and output.
First of all, what does static really mean? I remember my teacher saying that it represents a global variable which I can use anywhere in the program. As you can see I changed every variable to static to perhaps make my task easier.
Also, do I strictly need to use public static + type returned if I'm going to change something?
Let's say I want to change the values of an array (like I do in my program and use public static void) do I need to return something to actually change the values of the array or is it ok to use public static void?
If anyone also has any general pointers for what concerns my methods I would really appreciate it.
Your problem is in your initiate method:
return values;
processing(values);
Once you call return, your method stops. If you are using Eclipse (which I highly recommend), you should have gotten an error saying "Unreachable code," because there is simply no way for the program to execute your processing method.
I also saw this flaw in your output method.
First of all, what does static really mean? I remember my teacher
saying that it represents a global variable which I can use anywhere
in the program. As you can see I changed every variable to static to
perhaps make my task easier.
It depends on the context. There is a good overall description here. The meaning is different when applied to methods, fields, and classes. To say it makes variables "global" is a bit simplified.
Also, do I strictly need to use public static + type returned if I'm going to change something?
I'm a little confused about what you mean. A method declared as public static *return_type* has three separate, independent qualities:
public: It is accessible by any other class.
static: It does not require an instance of the class to function (see above link).
*return_type*: This is, of course, the return type.
These properties aren't really related to "changing something". Unless I misunderstood your question, the answer is: No, the method specifiers and return type have no impact on its ability to change something with the exception that static methods cannot modify non-static fields or call non-static methods of this (there is no this in static methods).
Let's say I want to change the values of an array (like I do in my program and use public static void) do I need to return something to actually change the values of the array or is it ok to use public static void?
What you do in the function is entirely independent of the access specifier and static-ness of it (with the above-mentioned exception that this does not exist in static methods). If your function has any side-effects like changing the values in an array (or any values for that matter), then it does it regardless of public, or static, or its return type.
Check out the More on Classes section of the official language tutorial. It is concise and well-written and should help complete your understanding of the general concepts you're asking about. Check out some of the other tutorials there as well if you'd like.
I understand how to pass a variable to another method and I even learned how to do multiple variables to a single method. My problem is I am trying to make a switch statement, when the user inputs a symptom for digoxin(medication for heart) in the statement I want to award him 10 points store it in a variable, and when the user enters another symptom I want to store that in variable as well in a new method. My problem is that after I send the variable to my method and continue with the program it inevitably resets it to zero, and thus dooming my efforts.
Code:
switch(input5) {
case "Vomiting":
score = 0;
num = 0;
score = num + 10;
getMethod(score,0);
System.out.println(getMethod(num));
JOptionPane.showMessageDialog (null,"you're correct") ;
break;
case "Dizziness":
JOptionPane.showMessageDialog (null,"you're correct") ;
score = num + 10;
getMethod(0,score);
break;
case "Confusion":
JOptionPane.showMessageDialog (null,"you're correct");
break;
case "Vision":
JOptionPane.showMessageDialog (null,"you're correct");
break;
default :
JOptionPane.showMessageDialog (null,"you're Wrong");
break;
}
...
static int getMethod(int total) {
int amount = total;
int amount2 = total2;
int result = amount + amount2;
return result;
}
The problem with this question is that it is so poorly phrased that it is difficult to understand what you actually think is happening. Unless we understand that, it is hard to answer it properly. So I'm just going to point out some things that appear to be errors in your thinking.
Variables don't "reset" in Java. In this case that the problem is that your getMethod method doesn't update score.
If a method returns a value, and that value isn't assigned to something then it is thrown away. In your case you are not assigning the value returned by getMethod in the places that you are calling it.
In Java, arguments are passed to methods "by value". The upshot is that something like this won't work:
int test = 1;
increment(test, 2);
public void increment(int value, int by) {
// FAIL - the local copy of "value" is incremented, but the
// the original "test" variable is not touched.
value = value + by;
}
Note that this has nothing to do with the names of the variable. The issue is that the variable inside the method is not "connected" in any way to the variable used at the call site. The method updates the former ... and not the latter.
A couple things that need to be said about your code:
It is important to indent your code consistently. There are style guides that tell you what to do. (We've reindented your code in a way that would be acceptable under most style guidelines.)
It is important to use sensible and informative names for things like methods, variables and classes. This helps readers understand what the code author intended the code to do / mean. In your case "getMethod" tells the reader nothing about what the method is supposed to do.
Methods should also have javadoc comments that state what they are supposed to do, what the arguments and results mean, and so on.
i think the issue here is that every time you enter something and enter your switch statement, it resets the score to 0.
switch(input5){
case "Vomiting":
score = 0;
I think you need to set score to 0 before the first input, and not reset it every time you put in vomiting. I can't exactly follow your code, please link the full class.
Try this:
score = getMethod(score, 0);
In java, primitives are "passed by value". The value, not the variable, is passed to the method. Changing the value within the method does nothing to the variable that was used to call the method.
Create a static global variable to maintain or persist the score. This will allow you to make subsequent calls to your method and still keep track of an accurate score.
So, create a global variable public static int score = 0;. Inside of your method you can get rid of the score variable initialization to zero score = 0; since you will use the global score variable.
I'm having some problems debugging my code as I can't work out where an array is getting updated. I have looked through all my class files and I'm completely stumped as to what is happening.
At the moment I have a setup whereby I read in a csv file and store the contents in a 2D array (public static double[][] myArray). I then pass this array into a method whenever a user presses a button.
The weird thing is that it works fine the first time, however on all subsequent clicks of the button the data has changed and I can't work out why. I have searched through the code and there are absolutely no references to the original array (i.e. myClass.myArray = newArray) apart from where I pass it into the method.
Is there a reason this is happening? Alternatively please could someone suggest a way to track when the variable gets updated/changed?
Here is a brief overview of the code...
Read in the csv dataset and save it in a variable (ClassA):
public static double[][] myDataset;
// ...
private static void readdDataset(String filePath)
{
CsvReader reader = new CsvReader();
myDataset = reader.readDataset(filePath, true);
}
This is the code used to set up the buttons' action:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
new RunProgram().execute(); // create a swing worker to run the code in bg
}
});
Here is a condensed down version the code in the SwingWorker class:
protected Void doInBackground()
{
Config cfgFile = someClass.createConfigFile();
someOtherClass.runMyProgram(cfgFile, ClassA.myDataset);
return null;
}
Finally here is the code to run the program:
public static void runRegression(Config cfgFile, double[][] dataset)
{
// Print out the first line in the array to see if it is the same every time (it should be!)
for(double value : dataset[0])
{
System.out.print( value + " ");
}
System.out.println();
// Do some other stuff....
}
Every method you pass this array to has the opportunity to change its contents. Your array is not immutable.
From the outline or project view, right-click on the variable, and select "Toggle Watchpoint".
(You can also set conditional breakpoints, which is handy.)
There doesn't need to be a reference to the original array, any reference to a static (mutable) object can manipulate its contents.
So I can't really be sure what is going on for sure since you seem to be dealing with 2d object and classes and I have a very basic understanding on them.
However it sounds like your problem aren’t really the 2d aspects but the storage of the data it uses. It also sounds like your button is the problem or it's before the button gets pressed and since you haven't given us the code I don't think anyone can help you.
Try making a temp bypass for the button so it just auto fires once and see what happens.
As for the debugging the normal way is to say
System.out.println("Array changed " + myArray[0] +" "+ myArray[1] );
This will print in a line on the console
Array changed 1 4 (if myArray[0] == 0 and myArray[1] == 4)
I can't help you anymore without seeing some code and I don't think anyone else can help.