I am trying to set up a program that saves users input into a file and then it outputs what the user entered as the average. I am using exception handling to detect if the user inputs letter. However, when the user inputs a letter it goes into an infinite loop. I am not able to figure out the issue. Please ignore the bad java. I just want it to function before I fix up the bad java.
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.util.Scanner;
public class W11dot1 {
public static void main(String[] args) throws IOException {
System.out.println("This program gets ten numbers from the user, then computes and displays the average.");
int numOf = 1;
double doMath = 0;
double[] numArray = new double[10];
do {
try{
for(int i = 0; i<10; i++){
Scanner input = new Scanner(System.in);
System.out.print("Enter Integer " + numOf + ": ");
double num = input.nextDouble();
numArray[i] = num;
numOf+=1;
}
}catch (InputMismatchException e){
System.out.println("Error: input must be an integer");
}
}while (numOf != 11);
File file = new File("Average.txt");
try {
PrintWriter output = new PrintWriter(file);
for(int y = 0; y<numArray.length; y++){
output.println(numArray[y]);
}
output.close();
} catch (IOException ex){
System.out.println("Error: with file");
}
Scanner input = new Scanner(file);
while (input.hasNext()){
double moreNums = input.nextDouble();
doMath += moreNums;
}
input.close();
double average = doMath/10;
System.out.printf("The average of the input values is %.2f", average);
System.out.println("\nGoodbye...");
}
}
Firstly you do not need nested loops while taking the input, the nested loops are causing the issue every time you enter a character.
Each time you enter a character and the scanner throws an exception and the inner for loop is restarted again. You can fix this by simply removing inner for loop (not really needed) and modifying numOf variable will help you achieve that, you can do something like this -
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.util.Scanner;
public class W11dot1 {
public static void main(String[] args) throws IOException {
System.out.println("This program gets ten numbers from the user, then computes and displays the average.");
double doMath = 0;
double[] numArray = new double[10];
int numOf = 0;
Scanner input = new Scanner(System.in);
do {
try {
System.out.printf("Enter Integer %d: ", (numOf+1));
double num = input.nextDouble();
numArray[numOf++] = num;
} catch (InputMismatchException e) {
System.out.println("Error: input must be an integer");
}
} while (numOf < 10);
input.close();
File file = new File("Average.txt");
try {
PrintWriter output = new PrintWriter(file);
for (int y = 0; y < numArray.length; y++) {
output.println(numArray[y]);
}
output.close();
} catch (IOException ex) {
System.out.println("Error: with file");
}
input = new Scanner(file);
while (input.hasNext()) {
double moreNums = input.nextDouble();
doMath += moreNums;
}
input.close();
double average = doMath / 10;
System.out.printf("The average of the input values is %.2f", average);
System.out.println("\nGoodbye...");
}
}
Also there are so many optimizations and cleaning that can made to the programs but as you said you will fix those.
Hope this helps!
You shouldn't declare your Scanner inside of your loop. As it stands now, you're initializing 10 different scanners and not closing any of them. It should be declared outside of your loop.
Your for nested inside of your do...while is also interesting. I don't think the inner for loop is necessary, because your do...while should already be taking care of the right bounds. If you do get rid of it, you would replace numArray[i] with numArray[numOf] (and start numOf at 0).
Related
I am trying to insert random strings into a .txt file. My code is as follows:
import java.util.*;
import java.io.*;
class fileProcessing{
public static void main (String[] args) throws Exception{
letter();
}
public static void letter() throws Exception{
int count = 0;
PrintStream out = new PrintStream(new File("nums.txt"));
while (count < 7 ){
Random rand = new Random();
int randomNum = 97 + rand.nextInt((122 - 97) + 1);
char a = (char)randomNum;
out.print(a);
count++;
}
}
}
I'm trying to put a row of 7 random letters in a .txt file about 400 or so times. My code allows me to put in only a row of 7 letters. I'm not sure how to get the other 399 lines in. Any help would be appreciated. Thanks!
Use a nested loop that contains the loop you have already written. What this does is, after you generate one word, do a new iteration, writing another word in your file.
import java.util.*
import java.io.*;
class FileProcessing
{
public static void main(String[] args) throws IOException
{
letters();
}
public static void letters() throws IOException
{
int count;
PrintStream out = new PrintStream(new File("nums.txt"));
/*Outer loop. When the loop on the inside finishes generating
*a word, this loop will iterate again.
*/
for(int i=0; i<400; ++i)
{
count=0;
/*your current while loop*/
while (count < 7)
{
Random rand = new Random();
int randomNum = 97 + rand.nextInt((122-97)+1);
char a = (char) randomNum;
out.print(a);
count++;
}
//print new line so all words are in a separate line
out.println();
}
//close PrintStream
out.close();
}
}
Learn more on nested loops here: http://www.javawithus.com/tutorial/nested-loops
Note: This question may look like a repetition of several question posted on the forum, but I am really stuck on this problem from quite some time and I am not able to solve this issue using the solutions posted for similar questions. I have posted my code here and need help to proceed further
So, here is my issue:
I am writing a Java GUI application which loads a file before performing any processing. There is a waiting time on an average of about 10-15 seconds during which the file is parsed. After this waiting time, what I get see on the GUI is,
The parsed file in the form of individual leaves in the JTree in a Jpanel
Some header information (example: data range) in two individual JTextField
A heat map generated after parsing the data in a different JPanel on the GUI.
The program connects to R to parse the file and read the header information.
Now, I want to use swing worker to put the file reading process on a different thread so that it does not block the EDT. I am not sure how I can build my SwingWorker class so that the process is done in the background and the results for the 3 components are displayed when the process is complete. And, during this file reading process I want to display a JProgressBar.
Here is the code which does the whole process, starting from selection of the file selection menu item. This is in the main GUI method.
JScrollPane spectralFilesScrollPane;
if ((e.getSource() == OpenImagingFileButton) || (e.getSource() == loadRawSpectraMenuItem)) {
int returnVal = fcImg.showOpenDialog(GUIMain.this);
// File chooser
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fcImg.getSelectedFile();
//JTree and treenode creation
DefaultMutableTreeNode root = new DefaultMutableTreeNode(file);
rawSpectraTree = new JTree(root);
DefaultTreeModel model = (DefaultTreeModel) rawSpectraTree.getModel();
try {
// R connection
rc = new RConnection();
final String inputFileDirectory = file.getParent();
System.out.println("Current path: " + currentPath);
rc.assign("importImagingFile", currentPath.concat("/importImagingFile.R"));
rc.eval("source(importImagingFile)");
rc.assign("currentWorkingDirectory", currentPath);
rc.assign("inputFileDirectory", inputFileDirectory);
rawSpectrumObjects = rc.eval("importImagingFile(inputFileDirectory,currentWorkingDirectory)");
rc.assign("plotAverageSpectra", currentPath.concat("/plotAverageSpectra.R"));
rc.eval("source(plotAverageSpectra)");
rc.assign("rawSpectrumObjects", rawSpectrumObjects);
REXP averageSpectraObject = rc.eval("plotAverageSpectra(rawSpectrumObjects)");
rc.assign("AverageMassSpecObjectToSpectra", currentPath.concat("/AverageMassSpecObjectToSpectra.R"));
rc.eval("source(AverageMassSpecObjectToSpectra)");
rc.assign("averageSpectraObject", averageSpectraObject);
REXP averageSpectra = rc.eval("AverageMassSpecObjectToSpectra(averageSpectraObject)");
averageSpectraMatrix = averageSpectra.asDoubleMatrix();
String[] spectrumName = new String[rawSpectrumObjects.asList().size()];
for (int i = 0; i < rawSpectrumObjects.asList().size(); i++) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode("Spectrum_" + (i + 1));
model.insertNodeInto(node, root, i);
}
// Expand all the nodes of the JTree
for(int i=0;i< model.getChildCount(root);++i){
rawSpectraTree.expandRow(i);
}
DefaultMutableTreeNode firstLeaf = ((DefaultMutableTreeNode)rawSpectraTree.getModel().getRoot()).getFirstLeaf();
rawSpectraTree.setSelectionPath(new TreePath(firstLeaf.getPath()));
updateSpectralTableandChartRAW(firstLeaf);
// List the min and the max m/z of in the respective data fields
rc.assign("dataMassRange", currentPath.concat("/dataMassRange.R"));
rc.eval("source(dataMassRange)");
rc.assign("rawSpectrumObjects", rawSpectrumObjects);
REXP massRange = rc.eval("dataMassRange(rawSpectrumObjects)");
double[] massRangeValues = massRange.asDoubles();
minMzValue = (float)massRangeValues[0];
maxMzValue = (float)massRangeValues[1];
GlobalMinMz = minMzValue;
GlobalMaxMz = maxMzValue;
// Adds the range values to the jTextField
minMz.setText(Float.toString(minMzValue));
minMz.validate();
minMz.repaint();
maxMz.setText(Float.toString(maxMzValue));
maxMz.validate();
maxMz.repaint();
// Update status bar with the uploaded data details
statusLabel.setText("File name: " + file.getName() + " | " + "Total spectra: " + rawSpectrumObjects.asList().size() + " | " + "Mass range: " + GlobalMinMz + "-" + GlobalMaxMz);
// Generates a heatmap
rawIntensityMap = gim.generateIntensityMap(rawSpectrumObjects, currentPath, minMzValue, maxMzValue, Gradient.GRADIENT_Rainbow, "RAW");
rawIntensityMap.addMouseListener(this);
rawIntensityMap.addMouseMotionListener(this);
imagePanel.add(rawIntensityMap, BorderLayout.CENTER);
coordinates = new JLabel();
coordinates.setBounds(31, 31, rawIntensityMap.getWidth() - 31, rawIntensityMap.getHeight() - 31);
panelRefresh(imagePanel);
tabbedSpectralFiles.setEnabledAt(1, false);
rawSpectraTree.addTreeSelectionListener(new TreeSelectionListener() {
#Override
public void valueChanged(TreeSelectionEvent e) {
try {
DefaultMutableTreeNode selectedNode =
(DefaultMutableTreeNode) rawSpectraTree.getLastSelectedPathComponent();
int rowCount = listTableModel.getRowCount();
for (int l = 0; l < rowCount; l++) {
listTableModel.removeRow(0);
}
updateSpectralTableandChartRAW(selectedNode);
} catch (RserveException e2) {
e2.printStackTrace();
} catch (REXPMismatchException e1) {
e1.printStackTrace();
}
}
});
spectralFilesScrollPane = new JScrollPane();
spectralFilesScrollPane.setViewportView(rawSpectraTree);
spectralFilesScrollPane.setPreferredSize(rawFilesPanel.getSize());
rawFilesPanel.add(spectralFilesScrollPane);
tabbedSpectralFiles.validate();
tabbedSpectralFiles.repaint();
rawImage.setEnabled(true);
peakPickedImage.setEnabled(false);
loadPeakListMenuItem.setEnabled(true); //active now
loadPeaklistsButton.setEnabled(true); //active now
propertiesMenuItem.setEnabled(true); // active now
propertiesButton.setEnabled(true); //active now
} catch (RserveException e1) {
JOptionPane.showMessageDialog(this,
"There was an error in the R connection. Please try again!", "Error",
JOptionPane.ERROR_MESSAGE);
} catch (REXPMismatchException e1) {
JOptionPane.showMessageDialog(this,
"Operation requested is not supported by the given R object type. Please try again!", "Error",
JOptionPane.ERROR_MESSAGE);
}
// hideProgress();
}
}
I tried creating a SwingWorker class, but I am totally confused how I can get all the three outputs on the GUI, plus have a progress bar. It is not complete, but I don't know how to proceed further.
public class FileReadWorker extends SwingWorker<REXP, String>{
private static void failIfInterrupted() throws InterruptedException {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Interrupted while loading imaging file!");
}
}
// The file that is being read
private final File fileName;
private JTree rawSpectraTree;
private RConnection rc;
private REXP rawSpectrumObjects;
private double[][] averageSpectraMatrix;
private Path currentRelativePath = Paths.get("");
private final String currentPath = currentRelativePath.toAbsolutePath().toString();
final JProgressBar progressBar = new JProgressBar();
// public FileReadWorker(File fileName)
// {
// this.fileName = fileName;
// System.out.println("I am here");
// }
public FileReadWorker(final JProgressBar progressBar, File fileName) {
this.fileName = fileName;
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
});
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
setProgress(0);
}
#Override
protected REXP doInBackground() throws Exception {
System.out.println("I am here... in background");
DefaultMutableTreeNode root = new DefaultMutableTreeNode(fileName);
rawSpectraTree = new JTree(root);
DefaultTreeModel model = (DefaultTreeModel) rawSpectraTree.getModel();
rc = new RConnection();
final String inputFileDirectory = fileName.getParent();
rc.assign("importImagingFile", currentPath.concat("/importImagingFile.R"));
rc.eval("source(importImagingFile)");
rc.assign("currentWorkingDirectory", currentPath);
rc.assign("inputFileDirectory", inputFileDirectory);
rawSpectrumObjects = rc.eval("importImagingFile(inputFileDirectory,currentWorkingDirectory)");
rc.assign("plotAverageSpectra", currentPath.concat("/plotAverageSpectra.R"));
rc.eval("source(plotAverageSpectra)");
rc.assign("rawSpectrumObjects", rawSpectrumObjects);
REXP averageSpectraObject = rc.eval("plotAverageSpectra(rawSpectrumObjects)");
rc.assign("AverageMassSpecObjectToSpectra", currentPath.concat("/AverageMassSpecObjectToSpectra.R"));
rc.eval("source(AverageMassSpecObjectToSpectra)");
rc.assign("averageSpectraObject", averageSpectraObject);
REXP averageSpectra = rc.eval("AverageMassSpecObjectToSpectra(averageSpectraObject)");
averageSpectraMatrix = averageSpectra.asDoubleMatrix();
for (int i = 0; i < rawSpectrumObjects.asList().size(); i++) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode("Spectrum_" + (i + 1));
model.insertNodeInto(node, root, i);
}
// Expand all the nodes of the JTree
for(int i=0;i< model.getChildCount(root);++i){
rawSpectraTree.expandRow(i);
}
return averageSpectra;
}
#Override
public void done() {
setProgress(100);
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
Any help would be very much appreciated.
The code below is giving me the error java.util.NoSuchElementException right after I Ctrl+Z
to indicate that the user input is complete. By the looks of it seems as if it does not know how to just end one method without messing with the other scanner object.
I try the hasNext method and I ended up with an infinite loop, either way is not working. As a requirement for this assignment I need to be able to tell the user to use Ctrl+Z or D depending on the operating system. Also I need to be able to read from a text file and save the final tree to a text file please help.
/* sample input:
CSCI3320
project
personal
1 HW1
1 HW2
1 2 MSS.java
2 p1.java
*/
import java.util.Scanner;
import java.util.StringTokenizer;
public class Directory {
private static TreeNode root = new TreeNode("/", null, null);
public static void main(String[] args) {
userMenu();
System.out.println("The directory is displayed as follows:");
root.listAll(0);
}
private static void userMenu(){ //Displays users menu
Scanner userInput = new Scanner(System.in);//Scanner option
int option = 0;
do{ //I believe the problem is here since I am not using userInput.Next()
System.out.println("\n 1. add files from user inputs ");
System.out.println("\n 2. display the whole directory ");
System.out.println("\n 3. display the size of directory ");
System.out.println("\n 0. exit");
System.out.println("\n Please give a selection [0-3]: ");
option = userInput.nextInt();
switch(option){
case 1: addFileFromUser();
break;
case 2: System.out.println("The directory is displayed as follows:");
root.listAll(0);
break;
case 3: System.out.printf("The size of the directory is %d.\n", root.size());
break;
default:
break;
}
}while( option !=0);
userInput.close();
}
private static void addFileFromUser() {
System.out.println("To terminate inp1ut, type the correct end-of-file indicator ");
System.out.println("when you are prompted to enter input.");
System.out.println("On UNIX/Linux/Mac OS X type <ctrl> d");
System.out.println("On Windows type <ctrl> z");
Scanner input = new Scanner(System.in);
while (input.hasNext()) { //hasNext being used Crtl Z is required to break
addFileIntoDirectory(input); // out of the loop.
}
input.close();
}
private static void addFileIntoDirectory(Scanner input) {
String line = input.nextLine();
if (line.trim().equals("")) return;
StringTokenizer tokens = new StringTokenizer(line);
int n = tokens.countTokens() - 1;
TreeNode p = root;
while (n > 0 && p.isDirectory()) {
int a = Integer.valueOf( tokens.nextToken() );
p = p.getFirstChild();
while (a > 1 && p != null) {
p = p.getNextSibling();
a--;
}
n--;
}
String name = tokens.nextToken();
TreeNode newNode = new TreeNode(name, null, null);
if (p.getFirstChild() == null) {
p.setFirstChild(newNode);
}
else {
p = p.getFirstChild();
while (p.getNextSibling() != null) {
p = p.getNextSibling();
}
p.setNextSibling(newNode);
}
}
private static class TreeNode {
private String element;
private TreeNode firstChild;
private TreeNode nextSibling;
public TreeNode(String e, TreeNode f, TreeNode s) {
setElement(e);
setFirstChild(f);
setNextSibling(s);
}
public void listAll(int i) {
for (int k = 0; k < i; k++) {
System.out.print('\t');
}
System.out.println(getElement());
if (isDirectory()) {
TreeNode t = getFirstChild();
while (t != null) {
t.listAll(i+1);
t = t.getNextSibling();
}
}
}
public int size() {
int s = 1;
if (isDirectory()) {
TreeNode t = getFirstChild();
while (t != null) {
s += t.size();
t = t.getNextSibling();
}
}
return s;
}
public void setElement(String e) {
element = e;
}
public String getElement() {
return element;
}
public boolean isDirectory() {
return getFirstChild() != null;
}
public void setFirstChild(TreeNode f) {
firstChild = f;
}
public TreeNode getFirstChild() {
return firstChild;
}
public void setNextSibling(TreeNode s) {
nextSibling = s;
}
public TreeNode getNextSibling() {
return nextSibling;
}
}
}
Exception Details:
/*Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at Directory.userMenu(Directory.java:36)
at Directory.main(Directory.java:21)*/
Your problem is this line:
option = userInput.nextInt(); //line 24
If you read the Javadoc, you will find that the nextInt() method can throw a NoSuchElementException if the input is exhausted. In other words, there is no next integer to get. Why is this happening in your code? Because you this line is in a loop once that first iteration completes (on the outer while loop) your initial input selection has been consumed. Since this is a homework, I am not going to write the code. But, if you remove the loop, you know this works at least once. Once you try to loop, it breaks. So I will give you these hints:
Change the do/while to a while loop.
Prompt the user once outside the loop.
Recreate the prompt and recapture the user input inside the loop.
For example, the code below can be used for the basis of your outer loop.
import java.util.Scanner;
public class GuessNumberGame {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Guess the secret number: (Hint: the secret number is 1)");
int guess = input.nextInt();
while (guess != 1) {
System.out.println("Wrong guess. Try again: ");
guess = input.nextInt();
}
System.out.println("Success");
input.close();
}
}
The reason why this works is because I don't reuse the same, exhausted, scanner input object to get the next integer. In your example, the initial input is inside the loop. The second time around, that input has already been consumed. Follow this pattern and you should be able to complete your assignment.
JavaME is quite sparse on features. Please list your favourite utility functions for making using it more like using proper Java, one per answer. Try to make your answers specific to Java ME.
Small Logging Framework
MicroLog
http://microlog.sourceforge.net/site/
Splitting a string
static public String[] split(String str, char c)
{
int l=str.length();
int count = 0;
for(int i = 0;i < l;i++)
{
if (str.charAt(i) == c)
{
count ++;
}
}
int first = 0;
int last = 0;
int segment=0;
String[] array = new String[count + 1];
for(int i=0;i<l;i++)
{
if (str.charAt(i) == c)
{
last = i;
array[segment++] = str.substring(first,last);
first = last;
}
if(i==l-1){
array[segment++] = str.substring(first,l);
}
}
return array;
}
Read a line from a reader. See also this question.
public class LineReader{
private Reader in;
private int bucket=-1;
public LineReader(Reader in){
this.in=in;
}
public boolean hasLine() throws IOException{
if(bucket!=-1)return true;
bucket=in.read();
return bucket!=-1;
}
//Read a line, removing any /r and /n. Buffers the string
public String readLine() throws IOException{
int tmp;
StringBuffer out=new StringBuffer();
//Read in data
while(true){
//Check the bucket first. If empty read from the input stream
if(bucket!=-1){
tmp=bucket;
bucket=-1;
}else{
tmp=in.read();
if(tmp==-1)break;
}
//If new line, then discard it. If we get a \r, we need to look ahead so can use bucket
if(tmp=='\r'){
int nextChar=in.read();
if(tmp!='\n')bucket=nextChar;//Ignores \r\n, but not \r\r
break;
}else if(tmp=='\n'){
break;
}else{
//Otherwise just append the character
out.append((char) tmp);
}
}
return out.toString();
}
}
Just a quick one, I want to continuously add digits to a string. The first thing I did is to remove the last character of the string, now digits starting from 1 should be continuously added to it. The snippet is below:
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class Class1
{
public static String source = "#box1";
static string dest;
public static void Main(String[] args)
{
try
{
if (source.Length > 0)
{
dest = source.Substring(0, source.Trim().Length - 1);
}
Console.WriteLine(dest);
Console.ReadLine();
}
catch(Exception e){ e.ToString(); }
}
}
}
The output should look like this:
#box1
#box2
#box3
#box4
#box5
and so on.....
If you have a max :
for (int i = 1; i <= max; i++)
{
Console.WriteLine("#Box" + i);
}
With no maximum, but that is not a good idea:
count = 1
while (1 > 0)
{
Console.WriteLine("#Box" + count);
count++;
}
You can also do no max with the for loop, but I just wanted to give you more options in loops.
Information on loops http://csharp.net-tutorials.com/basics/loops/
Thanks, guys,
I got it solved this way. Sorry that I have to post the real code I'm using it for. I'm much occupied than to edit the pseudo code again.
public static String RegistrationFailedPanels = UserValidations.RegistrationFailedPanels;
public static String CloseFailedPanel = UserValidations.CloseFailedPanel;
static int count = 0;
public void LoginFailed(String InputConstant, String FailedLogin)
{
++count;
InputConstant = RegistrationFailedPanels.Substring(0, RegistrationFailedPanels.Trim().Length-1);
FailedLogin = CloseFailedPanel.Substring(0, CloseFailedPanel.Trim().Length-1);
new LoginValidations(driver).WaitForATime(InputConstant +count);
driver.FindElement(By.CssSelector(FailedLogin +count)).Click();
}