This will probably sound like a dumb question to many of you but I'm a new student and I am trying to learn. This is a program that takes a roman numeral input from a user and converts it to it's decimal value. I am trying to test out this program, but I don't know exactly what I have to do in my main method in order to do so. I have the other methods for the calculating but now how am I supposed to test it out? Let me show you what I have:
public class RomanNumeralConverter {
public String getUserInput() {
Scanner numberInput = new Scanner (System.in);
System.out.print("Enter a roman numeral in uppercase: ");
String userInput = numberInput.next();
numberInput.close();
return userInput;
}
public static void romanToDecimal(String userInput) {
int decimal = 0;
int lastNumber = 0;
userInput = userInput.toUpperCase();
for (int x = userInput.length() - 1; x >= 0 ; x--) {
char convertToDecimal = userInput.charAt(x);
switch (convertToDecimal) {
case 'M':
decimal = processDecimal(1000, lastNumber, decimal);
lastNumber = 1000;
break;
case 'D':
decimal = processDecimal(500, lastNumber, decimal);
lastNumber = 500;
break;
case 'C':
decimal = processDecimal(100, lastNumber, decimal);
lastNumber = 100;
break;
case 'L':
decimal = processDecimal(50, lastNumber, decimal);
lastNumber = 50;
break;
case 'X':
decimal = processDecimal(10, lastNumber, decimal);
lastNumber = 10;
break;
case 'V':
decimal = processDecimal(5, lastNumber, decimal);
lastNumber = 5;
break;
case 'I':
decimal = processDecimal(1, lastNumber, decimal);
lastNumber = 1;
break;
}
}
System.out.println(decimal);
}
public static int processDecimal(int decimal, int lastNumber, int lastDecimal) {
if (lastNumber > decimal) {
return lastDecimal - decimal;
} else {
return lastDecimal + decimal;
}
}
public static void main(String[] args) {
romanToDecimal(getUserInput);
}
}
You could see that I tried plugging in getUserInputin to romanToDecimal but I know that I don't have those parameters in the main method, and I don't even think Java allows me to do that. But, I think this represents what I'm trying to do. Really what I want to do is:
System.out.println("The number you entered is " + userInput
System.out.println("The converted number is " + romanToDecimal
Maybe I am supposed to put this in a separate method?
There are a few changes you need:
If you're going to call your getUserInput method from main, you either need to make it static or create an instance of your class. I'd suggest making it a static method.
Currently your romanToDecimal method prints out the result - but it would be neater (in my view) if instead it returned the result, so you can print it in main
In romanToDecimal(getUserInput) you're trying to use getUserInput as if it's a variable, but it's a method.
After changing getUserInput to be static, and changing romanToDecimal to return a String instead of printing it, your main method could look like this:
public static void main(String[] args) {
String input = getUserInput();
String result = romanToDecimal(input);
System.out.println("The number you entered is " + input);
System.out.println("The converted number is " + result);
}
That would be fine as a program. Once you've got romanToDecimal as a method returning the result, you could also easily write unit tests for it, where the input was hard-coded into the test, and you checked the result. For example:
public void test5() {
String result = RomanNumeralConverter.romanToDecimal("V");
Assert.assertEquals(5, result);
}
... and lots more tests for everything you can think of. (Depending on the unit test framework you choose, you might be able to write a single piece of test code, and specify the input and expected results very compactly as parameters.)
Do this in the main method:
String input = getUserInput();
romanToDecimal(input);
This should get the code working like it should.
Just write unit tests testing out the romanToDecimal method with various inputs.
In Java JUnit is the most popular framework for doing this.
The test would look something like this:
#Test
public void testMyMethod() {
assertEquals("expected result", romanToDecimal("input"));
}
PS: In order to do this successfully you will need to return a String in your romanToDecimal method!
try this:
public static void main(String[] args) {
RomanNumeralConverter rnc = new RomanNumeralConverter();
String userInput = rnc.getUserInput(); // get user input
System.out.println(userInput); // print user input
Tests.romanToDecimal(userInput); // call the romanToDecimal static method to convert and print converted decimal
}
getUserInput is a function name. getUserInput() is a call to the function, called getUserInput, passing no arguments to it (empty parenthesis). That's what you want: call that function, and use the string it returns.
romanToDecimal(getUserInput()); in your main function should work.
You can also assign it to a variable first, so that you could print it out before calling romanToDecimal, and also, make romatToDecimal return a String rather than just printing it out. Then you could do something like this:
public static void main(String argv[]) {
String input = getUserInput();
String output = romanToDecimal(input);
System.out.ptinln("You enetered: " + input + "\nThe converted number is: " + output);
}
Oh, and as someone has pointed out, you need to make both methods you are calling static.
If you put the userInput method into your main method then pass userInput to romanToDecimal(getUserInput); in the main method it will work here is the code for the main method
public static void main(String[] args) {
Scanner numberInput = new Scanner (System.in);
System.out.print("Enter a roman numeral in uppercase: ");
String userInput = numberInput.next();
numberInput.close();
romanToDecimal(userInput);`
}
}
Related
I'm trying to write JUnit tests for a program that converts Fahrenheit degrees to Celsius degrees (and opposite). So my class looks like:
package asdf;
import java.util.Scanner;
public class UnitTesting {
public UnitTesting()
{
}
public int returnInt()
{
Scanner scanner = new Scanner(System.in);
int x = scanner.nextInt();
return x;
}
public double returnDouble()
{
Scanner scanner = new Scanner(System.in);
double x = scanner.nextDouble();
return x;
}
public double convertCtoF(double c) {
return 1.8*c+32;
}
public double convertFtoC(double f) {
return (5.0/9.0*(f-32));
}
public void menu()
{
int a;
do {
System.out.println("1 - convert C degrees to F degrees");
System.out.println("2 - convert F degrees to C degrees");
System.out.println("0 - exit");
a = returnInt();
switch(a)
{
case 1:
System.out.println(convertCtoF(returnDouble()));
break;
case 2:
System.out.println(convertFtoC(returnDouble()));
break;
case 0:
System.out.println("Bye!");
break;
default:
System.out.println("Choose 1, 2 or 0");
break;
}
}
while(a!=0);
}
public static void main(String [] args)
{
UnitTesting ut = new UnitTesting();
ut.menu();
}
}
test class:
package asdf;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class UnitTestingTests {
private UnitTesting ut;
#BeforeEach
public void init() {
ut = new UnitTesting();
}
#Test
void checkIfInputMismatch() {
ut.returnDouble();
//some_kind_of_assert
}
}
Since I wanted to test the user input's for various mismatch exceptions (NumberFormat, InputMismatch etc.) but I have no idea if this approach is possible for current methods returnDouble() and returnInt(). I was thinking of changing scanner to read input as a string (nextLine) but then extra parsing method would be needed. What would be needed to alter the methods/class to check if input is a number at all, or has a good format given by the user - in an "elegant" way?
Thank you
Some common techniques include:
Separate user interaction and program logic (here temperature conversion) into separate classes. Unit test your logic alone. Very often one does not unit test the user interaction, but integration tests the entire program including user interaction (you may use JUnit or some other tool for this).
Don’t create a new Scanner every time you read input. Use the same Scaner throughout. In this case it won’t be too hard to inject a different Scanner that reads from some other source than System.in for test purposes (if you really insisted on creating a new Scanner you might have method that in production creates a Scanner that reads from System.in and in test creates one that reads from some other source; but as I said, don’t bother).
You may also set System.in to some other input stream than the keyboard for test purposes. And/or similarly rewire System.out to a different output stream that allows to test what is written to it.
To control the input is integer, double or an invalid input, you need to take input as string. Then you can use defined parse methods of wrapper classes.
package asdf;
import java.util.Scanner;
public class UnitTesting {
public int returnInt()
{
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
try{
int x = Integer.parseInt(s);
return x;
}catch(NumberFormatException ex){ // handle your exception, there you can give some messages to user.
System.out.println("The input is invalid for integer.");
}
}
public double returnDouble()
{
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
try{
double x = Integer.parseDouble(s);
return x;
}catch(NumberFormatException ex){ // handle your exception, there you can give some messages to user.
System.out.println("The input is invalid for double.");
}
}
public double convertCtoF(double c) {
return 1.8*c+32;
}
public double convertFtoC(double f) {
return (5.0/9.0*(f-32));
}
public void menu()
{
int a;
do {
System.out.println("1 - convert C degrees to F degrees");
System.out.println("2 - convert F degrees to C degrees");
System.out.println("0 - exit");
a = returnInt();
switch(a)
{
case 1:
System.out.println(convertCtoF(returnDouble()));
break;
case 2:
System.out.println(convertFtoC(returnDouble()));
break;
case 0:
System.out.println("Bye!");
break;
default:
System.out.println("Choose 1, 2 or 0");
break;
}
}
while(a!=0);
}
public static void main(String [] args)
{
UnitTesting ut = new UnitTesting();
ut.menu();
}
}
And the other way to control : Pattern matching
String input=...;
String pattern ="-?\\d+";
if(input.matches("-?\\d+")){ // any positive or negetive integer or not!
...
}
I created a library System Rules that provide rules for populating System.in and reading output from System.out. Your Test may look like this:
package asdf;
import static org.junit.Assert.*;
import org.junit.Test;
public class UnitTestingTests {
#Rule
public final TextFromStandardInputStream systemInMock
= emptyStandardInputStream();
private UnitTesting ut;
#Test
void checkIfInputMismatch() {
systemInMock.provideLines("1.23");
double value = ut.returnDouble();
//some_kind_of_assert
}
}
Unfortunately System Rules does only support JUnit 4. I'm working on a test framework independent alternative for System Rules.
I am trying to make this method print one of the four string messages contained within String[] strArr. I have tried doing this by calling the method in the main method, by typing many different forms of simpleArray(); and I have tried filling the parenthesis, writing it several different ways but nothing has worked. I have actually been working on it for days, and usually I give up and move on to a different part of the code.
Though it may seem impractical, I do need the method to be written similarly to the way it is because my project criteria states it must contain one argument and return void.
public static void simpleArray(String[] greetings) {
String[] strArr = {"Welcome To CWU BANK!", "Thank you for using CWU ATM!", "Please insert DEBIT card", "We value your business!"};
int i = (int)(Math.random() * strArr.length);
System.out.println(strArr[i]);
}
here is my main method, where I try to call the custom method in line 6.
public static void main(String[] args) throws IOException {
double amountToWithdrawl;
double saveRandomBalance;
double remainingBalance;
simpleArray();
printStartupMessage();
Scanner keyboard = new Scanner(System.in);
Scanner keyboardDouble = new Scanner(System.in);
saveRandomBalance = getRandomBalance();
System.out.println("CHECKING BALANCE**** $" + saveRandomBalance);
System.out.println("Would you like to withdrawl from CHECKING****? Y/N");
String proceedWithWithdrawl = keyboard.nextLine();
while (!proceedWithWithdrawl.equalsIgnoreCase("y") && !proceedWithWithdrawl.equalsIgnoreCase("n")
&& !proceedWithWithdrawl.equalsIgnoreCase("yes") && !proceedWithWithdrawl.equalsIgnoreCase("no"))
{
System.out.println("Invalid response. Enter [Y] or [N].");
proceedWithWithdrawl = keyboard.next();
}
switch(proceedWithWithdrawl)
{
case "N":
case "n":
case "nO":
case "NO":
case "No":
System.out.println("Returning card... please wait...");
System.out.println("Card returned. Thank you for using CWU Bank!");
break;
case "yeS":
case "YEs":
case "yEs":
case "yES":
case "YeS":
case "YES":
case "Yes":
case "yes":
case "y":
case "Y":
System.out.println("Enter amount to withdrawl: ");
amountToWithdrawl = keyboardDouble.nextDouble();
remainingBalance = saveRandomBalance - amountToWithdrawl;
remainingBalance = Math.round(remainingBalance * 100);
remainingBalance = remainingBalance/100;
if (amountToWithdrawl % 20 == 0 && amountToWithdrawl <= saveRandomBalance)
{
System.out.println("Dispensing...");
System.out.println("ACCOUNT BALANCE: $" + remainingBalance);
System.out.println("$" + amountToWithdrawl + " has been withdrawn from CHECKING****");
System.out.println("Returning card... please wait...");
System.out.println("Card returned. Thank you for using CWU Bank!");
//CallDollarBill.dollarBill();
}
else if (amountToWithdrawl > saveRandomBalance)
{
System.out.println("Insufficient Balance.");
}
else if (amountToWithdrawl % 20 != 0)
{
System.out.println("Please enter multiples of 20.");
}
//else
//{
// System.out.println("invalid input");
//}
}
}
now, the error it provides is as follows.
firstDraftFinal.java:69: error: method simpleArray in class firstDraftFinal cannot be applied to given types;
simpleArray();
^
required: String[]
found: no arguments
reason: actual and formal argument lists differ in length
1 error
I understand that part of the problem is probably int i (and strrArr) are integers, but I do not know what to do about this. I hired a tutor, but I ran out of time. I am also aware that the switch statement is not efficient, I will be changing that.
Thank you.
Your current code specifies a parameter that is not used; while it's unclear why you would want to do this, you can simply pass null. However, maybe what you intended was to pass the list of greetings; i.e. see second version below.
class Test {
public static void main(String[] args) {
// Per your current code.
for (int i=0; i<10; i++) simpleArray(null);
System.out.println("");
// What you may be looking for.
String[] strArr = { "Welcome To CWU BANK!", "Thank you for using CWU ATM!", "Please insert DEBIT card",
"We value your business!" };
for (int i=0; i<10; i++) simpleArray2(strArr);
}
public static void simpleArray(String[] greetings) {
String[] strArr = { "Welcome To CWU BANK!", "Thank you for using CWU ATM!", "Please insert DEBIT card",
"We value your business!" };
int i = (int) (Math.random() * strArr.length);
System.out.println(strArr[i]);
}
public static void simpleArray2(String[] greetings) {
int i = (int) (Math.random() * greetings.length);
System.out.println(greetings[i]);
}
}
You have compile error because you didn't pass any arguments to method that require them, just pass to your method any string array, because you don't use passed argument in this method:
public static void main(String[] args) throws IOException {
double amountToWithdrawl;
double saveRandomBalance;
double remainingBalance;
simpleArray(new String[0]);
printStartupMessage();
To continue refactor your code you may want to get rid of this argument (pay attention if other parts of code may use it) and rewrite it like this:
public static void printGreetings() {
String[] greetings = {"Welcome To CWU BANK!",
"Thank you for using CWU ATM!",
"Please insert DEBIT card",
"We value your business!"
};
int random = new Random().nextInt(greetings.length);
System.out.println(greetings[random]);
}
In my class we needed to make a memory calculator in Java. Im really new to Java and had help making the program. Turned it in and the teacher said "Please separate the MemoryCalculator class from the class with the main() method. Currently the way you have created the class, there is no reason to create an instance of the class. But the point of the assignment is to use separate classes and objects." Its been a super long week and midterms and just lost at this time. Any help would be great.
import java.util.Scanner;
public class MemoryCalculator {
private double currentValue;
//Methods
//Scanner
public static int displayMenu(){
Scanner input = new Scanner(System.in);
System.out.print("Lets do some math! \nMenu \n1. Add \n2. Subtract \n3. Multiply \n4. Divide \n"
+ "5. Clear \n6. Quit \n\nWhat would you like to do? ");
int menuChoice = input.nextInt();
return menuChoice;
}
public static double getOperand(String prompt) {
Scanner input = new Scanner(System. in );
double operand;
System.out.println(prompt);
operand = input.nextDouble();
return operand;
}
//Current Value
//Gets
public double getCurrentValue() {
return currentValue;
}
//Setter
public void setCurrentValue(double currentValue) {
this.currentValue = currentValue;
}
//Add
public void add(double operand2) {
currentValue += operand2;
}
//Subtract
public void subtract(double operand2) {
currentValue -= operand2;
}
//Multiply
public void multiply(double operand2) {
currentValue *= operand2;
}
//Divide
public void divide(double operand2) {
if (operand2==0){
setCurrentValue(0);
}
currentValue /=operand2;
}
//Clear
public void clear() {
currentValue = 0;
}
//Main part of the calculator
public static void main(String[] args) {
MemoryCalculator instance = new MemoryCalculator();
double operand;
boolean repeat = true;
while (repeat) {
System.out.println("The current value is: " + instance.getCurrentValue() + "\n");
int menuChoice;
menuChoice = displayMenu();
if (menuChoice > 6 || menuChoice < 1){
System.out.println("I'm sorry, " + menuChoice + " wasn't one of the options\n");
}
switch(menuChoice){
case 1:
operand = getOperand("What is the second number?");
instance.add(operand);
break;
case 2:
operand = getOperand("What is the second number?");
instance.subtract(operand);
break;
case 3:
operand = getOperand("What is the second number?");
instance.multiply(operand);
break;
case 4:
operand = getOperand("What is the second number?");
instance.divide(operand);
break;
case 5:
instance.clear();
break;
case 6:
System.out.println("Goodbye have a great day");
System.exit(0);
break;
}
}
}
}
What it looks like you did with your program was create one, single, class that holds all of the code for your calculator program, within which you instantiated an object of the same class.
What your teacher wants instead, is for you to have two separate classes, one which contains the code that makes the calculator work, and another class where you instantiate an object of the first class, and call the methods contained within that class.
For your assignment, what I would suggest would be to create a new class, perhaps called Main, where your program's Main() method will be, and keep all of the code for the calculator program in the MemoryCalculator class. From there, you can instantiate an object of MemoryCalculator class (which you already did, called instance) and use method calls to reference methods and attributes from within the MemoryCalculator class.
This may require reworking some of your code so that it runs properly, given that you'll be calling most of it from an object of the MemoryCalculator class, but it should be doable.
This is my second time asking this question because this assignment is due tomorrow, and I am still unclear how to progress in my code! I am in an AP Computer programming class so I am a complete beginner at this. My goal (so far) is to multiply two fractions. Is there any way to use a variable inside a particular method outside of that method in another method? I hope that wasn't confusing, thank you!!
import java.util.Scanner;
import java.util.StringTokenizer;
public class javatest3 {
static int num1 = 0;
static int num2 = 0;
static int denom1 = 0;
static int denom2 = 0;
public static void main(String[] args){
System.out.println("Enter an expression (or \"quit\"): "); //prompts user for input
intro();
}
public static void intro(){
Scanner input = new Scanner(System.in);
String user= input.nextLine();
while (!user.equals("quit") & input.hasNextLine()){ //processes code when user input does not equal quit
StringTokenizer chunks = new StringTokenizer(user, " "); //parses by white space
String fraction1 = chunks.nextToken(); //first fraction
String operand = chunks.nextToken(); //operator
String fraction2 = chunks.nextToken(); //second fraction
System.out.println("Fraction 1: " + fraction1);
System.out.println("Operation: " + operand);
System.out.println("Fraction 2: " + fraction2);
System.out.println("Enter an expression (or \"quit\"): "); //prompts user for more input
while (user.contains("*")){
parse(fraction1);
parse(fraction2);
System.out.println("hi");
int num = num1 * num2;
int denom = denom1 * denom2;
System.out.println(num + "/" + denom);
user = input.next();
}
}
}
public static void parse(String fraction) {
if (fraction.contains("_")){
StringTokenizer mixed = new StringTokenizer(fraction, "_");
int wholeNumber = Integer.parseInt(mixed.nextToken());
System.out.println(wholeNumber);
String frac = mixed.nextToken();
System.out.println(frac);
StringTokenizer parseFraction = new StringTokenizer(frac, "/"); //parses by forward slash
int num = Integer.parseInt(parseFraction.nextToken());
System.out.println(num);
int denom = Integer.parseInt(parseFraction.nextToken());
System.out.println(denom);
}
else if (!fraction.contains("_") && fraction.contains("/")){
StringTokenizer parseFraction = new StringTokenizer(fraction, "/"); //parses by forward slash
int num = Integer.parseInt(parseFraction.nextToken());
System.out.println(num);
int denom = Integer.parseInt(parseFraction.nextToken());
System.out.println(denom);
}else{
StringTokenizer whiteSpace = new StringTokenizer(fraction, " ");
int num = Integer.parseInt(whiteSpace.nextToken());
System.out.println(num);
}
}}
Is there any way to use a variable inside a particular method outside of that method in another method?
Yes you can do that. You can declare a variable in a method, use it there and pass it to another method, where you might want to use it. Something like this
void test1() {
int var = 1;
System.out.println(var); // using it
test2(var); // calling other method and passing the value of var
}
void test2(int passedVarValue) {
System.out.println(passedVarValue); // using the passed value of the variable
// other stuffs
}
Hi I was attempting to create a calculator that can add subtract multiply and divide to challenge myself but find myself getting stuck around the switch part:(I will point out the errors within the switch message that say "The method addition etc(String[]) in the type addition etc is not applicable for the arguments ()." I believe the problem lies within the public void of the other classes.
Script:
public class ComputronCalc {
public static void main(String args[]) {
int mode;
mode = 1;
Addition ADD = new Addition();
Subtraction SUB = new Subtraction();
Multiplication MUL = new Multiplication();
Division DIV = new Division();
System.out.println("Hello welcome to the Computron fully functional calculator, coded by Samuel Cole, designed by Dwight Schrute.");
switch(mode) {
case 1:
ADD.Addition();<-----------addition is underlined in red
break;
case 2:
SUB.Subtraction();<-------------same
break;
case 3:
MUL.Multiplication();<---------------same
break;
case 4:
DIV.Division();<----------------same
break;
default:
System.out.println("You have not selected a mode, do so by editing the mode variable in the source.");
}
System.out.println("Thank you for choosing Computron.");
}
}
import java.util.Scanner;
public class Addition {
public void Addition(String Args[]) {
Scanner input = new Scanner(System.in);
double fnum, snum, answer;
System.out.println("Type the first number you desire to calculate.");
fnum = input.nextDouble();
System.out.println("Type the second number you desire to calculate.");
snum = input.nextDouble();
System.out.println("Calculating...");
answer = fnum + snum;
System.out.println(answer);
}
}
import java.util.Scanner;
public class Multiplication {
public void Multiplication(String Args[]) {
Scanner input = new Scanner(System.in);
double fnum, snum, answer;
System.out.println("Type the first number you desire to calculate.");
fnum = input.nextDouble();
System.out.println("Type the second number you desire to calculate.");
snum = input.nextDouble();
System.out.println("Calculating...");
answer = fnum * snum;
System.out.println(answer);
}
}
import java.util.Scanner;
public class Division {
public void Division(String Args[]) {
Scanner input = new Scanner(System.in);
double fnum, snum, answer;
System.out.println("Type the first number you desire to calculate.");
fnum = input.nextDouble();
System.out.println("Type the second number you desire to calculate.");
snum = input.nextDouble();
System.out.println("Calculating...");
answer = fnum / snum;
System.out.println(answer);
}
}
note: I'm using eclipse so each class is on like a different page.
Your methods expect the argument "args", which you don't use. Remove it. For example:
public void Addition(String Args[]) {
becomes:
public void Addition() {
(by the way, your code does not follow Oracle Java Naming Convention)
While the acute problem is that you need to change your method signatures to not have any parameters or change the method invocation to send a parameter, I think there is a better solution you should concider.
Change the methods in your operation classes to be constructors:
public class Addition {
public Addition() {
//...
}
}
Then you do not need to instantiate all the operations for each run and the switch becomes:
switch(mode) {
case 1:
Addition();
break;
case 2:
Subtraction();
break;
case 3:
Multiplication();
break;
case 4:
Division();
break;
default:
System.out.println("You have not selected a mode, do so by editing the mode variable in the source.");
}
Do not have any parameter (in this program, the String[] args parameter) for the function inside the four operator classes. Your program should work without them.
public class Addition {
public Addition() {
//...
}
}
Same applies for other classes too.
public class Subtraction {
public Subtraction() {
//...
}
}
public class Multiplication{
public Multiplication() {
//...
}
}
public class Division {
public Division() {
//...
}
}