I made a simple chatbot that responds to certain prompts with string output in Java. I want this program to output it's responses to an element on an HTML based webpage, and read input from the a different element on the same page.
Does anyone know how I could accomplish this?
Here's the code if you're interested:
import java.util.Scanner;
public class botRun
{
#SuppressWarnings("resource")
public static void main(String[] args)
{
PepperBot bot = new PepperBot();
Scanner in = new Scanner(System.in);
String input = in.nextLine();
while(true)
{
if(bot.shouldRespond(input))
{
System.out.println(bot.getRespond(input));
}
input = in.nextLine();
}
}
}
all other methods, "shouldRespond(String x)" and getRespond(String x) are in a separate class for object "PepperBot()" and check if the bot should respond and get the appropriate response respectively.
Pretty much any solution will do, as long as it isn't costly.
Related
I am trying to use multiple classes not to bulk the whole entirety of the calculator in the main class. I was planning to use switch but I have been stuck on trying to combine User Input when it comes to your choice of operation.
ApplesUserInput.java
package applesuserinput;
import java.util.Scanner;
public class ApplesUserInput {
public static void main(String args[]){
calculator c1 = new calculator();
System.out.println("Hello! Welcome to my Calculator.");
System.out.print("You may add (A), subtract (S), multiply (M) or divide (D) two different numbers. Please select one of the letters for your desired operation: ");
calculator.geta();
}
}
calculator.java
package applesuserinput;
import java.util.Scanner;
public class calculator {
public static void geta(){
Scanner scan = new Scanner(System.in);
String a;
a = scan.nextLine();
}
}
So far it compiles and runs well but I cannot get the switch statement to recognize the a String from my geta(). So I'm pretty much stuck here right now.
Your geta() method isn't returning anything, nor have you assigned the result to anything.
It should be:
public static String geta(){
Scanner scan = new Scanner(System.in);
String a = scan.nextLine();
return a;
}
And in ApplesUserInput.java, it should be:
String a = calculator.geta();
I have made two programs for an assignment. Now my professor wants me to put both programs into the same file and use a switch to create a menu where the user can use to choose what program they want to run. How do I do this? I will copy-paste both of my original programs below.
Program 1:
import java.util.Scanner;
public class ReadName {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Please type in your full name: ");
String names = scanner.nextLine();
String[] namesSep = names.split(" ");
int lastString = namesSep.length - 1;
System.out.println(namesSep[0]);
System.out.println(namesSep[lastString]);
}
}
Program 2:
import java.util.Scanner;
public class FindSmith {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Type in your list of names: ");
String names = scanner.nextLine();
String[] namesSep = names.split(",");
for (int i=0; i<namesSep.length; i++) {
if (namesSep[i].contains("Smith")) {
System.out.println(namesSep[i]);
}
}
}
}
You have two classes that do work in a single main() method each.
Start with: moving the content of that main() methods into another static method within each class, like:
import java.util.Scanner;
public class ReadName {
public static void main(String[] args) {
askUserForName();
}
public static void askUserForName() {
Scanner scanner = new Scanner(System.in);
System.out.print("Please type in your full name: ");
...
}
}
Do that for both classes, and make sure that both classes still do what
you want them to do.
Then create a third class, and copy those two other methods into the new class.
Then write a main() method there, that asks the user what to do, and then
runs one of these two methods from there.
Alternatively, you could also do
public class Combo {
public static void main(String[] args) {
...
if (userWantsToUseClassOne) {
Readme.main(new String[0]);
} else {
FindSmith.main(...
In other words: as long as you keep your classes in the same directory, you can directly re-use what you already have. But it is much better practice to put your code into meaningful methods, like I showed first.
As you might know, each Java program only has a single entry point; defined by the method public static void main(String[] args). As each class can define this method only once and you have to specify the class the method is in in your META-INF.MF file, it is impossible to have multiple entry points.
So you have to implement the logic that controls the program flow and respects the user's choice on your own. You can e.g. ask the user via the command line what kind of subprogram they want to execute.
you can use multiple method instead of multiple class . and call all method from your main method should be solve your problem.....
public class Combo{
public void readName(){
// place here all code form main method block of ReadName class
}
public void findSmith(){
// place here all code form main method block of FindSmith class
}
public static void main(String[] args) {
Combo c = new Combo();
c.readName();
c.findSmith();
}
}
Rather than creating two classes, you can create single class with one main method. Where you can create 3 switch cases.
1) To call ReadName (RN)
2) To call FindSmith (FS)
3) To break the code (BR)
After every execution you can again call main method. (Optional) I have added that to continue the flow.
package test.file;
import java.util.Scanner;
public class Test {
private final static Scanner scanner = new Scanner(System.in);
//public class ReadName
public static void main(final String[] args) {
switch (scanner.nextLine()) {
case "FS" :
findSmith();
break;
case "RN" :
readName();
break;
case "BR" :
break;
default :
System.out.println("Please enter valid value. Valid values are FS and RN. Enter BR to break.");
main(null);
}
}
private static void findSmith() {
System.out.println("Type in your list of names: ");
final String names = scanner.nextLine();
final String[] namesSep = names.split(",");
for (int i = 0; i < namesSep.length; i++) {
if (namesSep[i].contains("Smith")) {
System.out.println(namesSep[i]);
}
}
System.out.println("Please enter valid value. Valid values are FS and RN. Enter BR to break.");
main(null);
}
private static void readName() {
System.out.print("Please type in your full name: ");
final String names = scanner.nextLine();
final String[] namesSep = names.split(" ");
final int lastString = namesSep.length - 1;
System.out.println(namesSep[0]);
System.out.println(namesSep[lastString]);
System.out.println("Please enter valid value. Valid values are FS and RN. Enter BR to break.");
main(null);
}
}
Welcome to this community! As #Stultuske comments, your better approach is convert your main methods to regular methods and invoke them depending on the user's input.
The steps you should follow are:
Join both main methods to a single class file.
Convert both main methods to regular methods:
Change their name from "main" to any other name. Usually, using their functionality as a name is a good practice. In your case, you can use the class names you already defined ("ReadName" and "FindSmith").
Remove their input parameter "args": as they are no more the main method of a class, they won't be reciving any args parameter, unless you specify it.
Define a new main method which reads from the scanner and call your new methods acordingly to the user input.
I'm struggling with a specific method which takes in a String parameter. The promptString method will print its parameter to the user as a prompt, and then return a String that is the result of reading the console via the nextLine() method. For this program you will use nextLine() exclusively.
I've prompted the user with a question using a parameter, and then used nextLine to read the string but after that I am a bit lost. How can I get the method to print to the console?
import java.util.*;
public class StarWarsName{
public static void main (String [] args) {
promptString("Enter your first name: ");
}
public static String promptString (String n) {
Scanner console = new Scanner(System.in);
String first = console.nextline();
return first.trim();
}
}
I think you are over-thinking this thing. Just print it to the console.
public static void main(String[]args){
String result = promptString("Enter your first name: ");
System.out.println(result);
}
I am trying to create some JUnit tests for a method that requires user input. The method under test looks somewhat like the following method:
public static int testUserInput() {
Scanner keyboard = new Scanner(System.in);
System.out.println("Give a number between 1 and 10");
int input = keyboard.nextInt();
while (input < 1 || input > 10) {
System.out.println("Wrong number, try again.");
input = keyboard.nextInt();
}
return input;
}
Is there a possible way to automatically pass the program an int instead of me or someone else doing this manually in the JUnit test method? Like simulating the user input?
You can replace System.in with you own stream by calling System.setIn(InputStream in).
InputStream can be a byte array:
InputStream sysInBackup = System.in; // backup System.in to restore it later
ByteArrayInputStream in = new ByteArrayInputStream("My string".getBytes());
System.setIn(in);
// do your thing
// optionally, reset System.in to its original
System.setIn(sysInBackup);
Different approach can be make this method more testable by passing IN and OUT as parameters:
public static int testUserInput(InputStream in,PrintStream out) {
Scanner keyboard = new Scanner(in);
out.println("Give a number between 1 and 10");
int input = keyboard.nextInt();
while (input < 1 || input > 10) {
out.println("Wrong number, try again.");
input = keyboard.nextInt();
}
return input;
}
To test drive your code, you should create a wrapper for system input/output functions. You can do this using dependency injection, giving us a class that can ask for new integers:
public static class IntegerAsker {
private final Scanner scanner;
private final PrintStream out;
public IntegerAsker(InputStream in, PrintStream out) {
scanner = new Scanner(in);
this.out = out;
}
public int ask(String message) {
out.println(message);
return scanner.nextInt();
}
}
Then you can create tests for your function, using a mock framework (I use Mockito):
#Test
public void getsIntegerWhenWithinBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask(anyString())).thenReturn(3);
assertEquals(getBoundIntegerFromUser(asker), 3);
}
#Test
public void asksForNewIntegerWhenOutsideBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask("Give a number between 1 and 10")).thenReturn(99);
when(asker.ask("Wrong number, try again.")).thenReturn(3);
getBoundIntegerFromUser(asker);
verify(asker).ask("Wrong number, try again.");
}
Then write your function that passes the tests. The function is much cleaner since you can remove the asking/getting integer duplication and the actual system calls are encapsulated.
public static void main(String[] args) {
getBoundIntegerFromUser(new IntegerAsker(System.in, System.out));
}
public static int getBoundIntegerFromUser(IntegerAsker asker) {
int input = asker.ask("Give a number between 1 and 10");
while (input < 1 || input > 10)
input = asker.ask("Wrong number, try again.");
return input;
}
This may seem like overkill for your small example, but if you are building a larger application developing like this can payoff rather quickly.
One common way to test similar code would be to extract a method that takes in a Scanner and a PrintWriter, similar to this StackOverflow answer, and test that:
public void processUserInput() {
processUserInput(new Scanner(System.in), System.out);
}
/** For testing. Package-private if possible. */
public void processUserInput(Scanner scanner, PrintWriter output) {
output.println("Give a number between 1 and 10");
int input = scanner.nextInt();
while (input < 1 || input > 10) {
output.println("Wrong number, try again.");
input = scanner.nextInt();
}
return input;
}
Do note that you won't be able to read your output until the end, and you'll have to specify all of your input up front:
#Test
public void shouldProcessUserInput() {
StringWriter output = new StringWriter();
String input = "11\n" // "Wrong number, try again."
+ "10\n";
assertEquals(10, systemUnderTest.processUserInput(
new Scanner(input), new PrintWriter(output)));
assertThat(output.toString(), contains("Wrong number, try again.")););
}
Of course, rather than creating an overload method, you could also keep the "scanner" and "output" as mutable fields in your system under test. I tend to like keeping classes as stateless as possible, but that's not a very big concession if it matters to you or your coworkers/instructor.
You might also choose to put your test code in the same Java package as the code under test (even if it's in a different source folder), which allows you to relax the visibility of the two parameter overload to be package-private.
I managed to find a simpler way. However, you have to use external library System.rules by #Stefan Birkner
I just took the example provided there, I think it couldn't have gotten more simpler:
import java.util.Scanner;
public class Summarize {
public static int sumOfNumbersFromSystemIn() {
Scanner scanner = new Scanner(System.in);
int firstSummand = scanner.nextInt();
int secondSummand = scanner.nextInt();
return firstSummand + secondSummand;
}
}
Test
import static org.junit.Assert.*;
import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.TextFromStandardInputStream;
public class SummarizeTest {
#Rule
public final TextFromStandardInputStream systemInMock
= emptyStandardInputStream();
#Test
public void summarizesTwoNumbers() {
systemInMock.provideLines("1", "2");
assertEquals(3, Summarize.sumOfNumbersFromSystemIn());
}
}
The problem however in my case my second input has spaces and this makes the whole input stream null!
You might start by extracting out the logic that retrieves the number from the keyboard into its own method. Then you can test the validation logic without worrying about the keyboard. In order to test the keyboard.nextInt() call you may want to consider using a mock object.
I have fixed the problem about read from stdin to simulate a console...
My problems was I'd like try write in JUnit test the console to create a certain object...
The problem is like all you say : How Can I write in the Stdin from JUnit test?
Then at college I learn about redirections like you say System.setIn(InputStream) change the stdin filedescriptor and you can write in then...
But there is one more proble to fix... the JUnit test block waiting read from your new InputStream, so you need create a thread to read from the InputStream and from JUnit test Thread write in the new Stdin... First you have to write in the Stdin because if you write later of create the Thread to read from stdin you likely will have race Conditions... you can write in the InputStream before to read or you can read from InputStream before write...
This is my code, my english skill is bad I hope all you can understand the problem and the solution to simulate write in stdin from JUnit test.
private void readFromConsole(String data) throws InterruptedException {
System.setIn(new ByteArrayInputStream(data.getBytes()));
Thread rC = new Thread() {
#Override
public void run() {
study = new Study();
study.read(System.in);
}
};
rC.start();
rC.join();
}
I've found it helpful to create an interface that defines methods similar to java.io.Console and then use that for reading or writing to the System.out. The real implementation will delegate to System.console() while your JUnit version can be a mock object with canned input and expected responses.
For example, you'd construct a MockConsole that contained the canned input from the user. The mock implementation would pop an input string off the list each time readLine was called. It would also gather all of the output written to a list of responses. At the end of the test, if all went well, then all of your input would have been read and you can assert on the output.
Hey everyone my name is Abraham Esparza and I am currently teaching myself JAVA. Currently I am trying to create a program that asks feedback from the user. I saw several examples of an “Old Mac Donald” program and I wanted to modify it so that it contains a custom method and prompts the user for feedback. I want the program to start with "Old Macdonald had a farm" and prompt the user to input "please enter EIEIO" if the user enter anything else other than "EIEIO" the program will ask them to try again. If the user types "EIEIO" the program moves to the rest of the song.
Please help.
here is what I have so far
package pkgnew.newthod;
import java.lang.String;
import java.util.Scanner;
public class NewNewthod {
public static void main(String[] args) {
System.out.println("Old MacDonald Had a Farm");
System.out.println( );
// print first verse with a method call
int EIEIO, User, message;
// print second and third verses (not done yet)
}
// This method prints the Old Macdonald line
public void User( ) {
System.out.println("Old Macdonald had a farm, E-I-E-I-O");
Scanner input = new Scanner(System.in);
String message = input.nextLine();
System.out.println(EIEIO(message));
}
public String EIEIO(String message){
System.out.printf("please enter EIEIO");
if (message.equals("E-I-E-I-O"))
return "please enter EIEIO";
return EIEIO(String (message));}
else // after the the user types EIEIO i want the program to proceed the next section, but i get illegal start of type
{
System.out.println("With a moo-moo here and a moo-moo there");
System.out.println("And on his farm he had a cow, E-I-E-I-O");
System.out.println("Here a moo there a moo");
System.out.println("Everywhere a moo-moo");
System.out.println( );{}
}
}
Your code quite messy and I can only offer advice but not an answer.
Re: Good Practice:
Use camelcase.
INDENT YOUR CODE.
Be as specific as you can regarding what your problem is.
Just solve little bits of your problem at a time. I see no reason to use Scanner() or overcomplicate things. Just keep it simple.
Always remember KISS and WIMP. (KISS is Keep It Simple Stupid) (WIMP is What Is My Problem) WIMP is my own invention for problem solving. ;D
Re: Your Code:
Your methods need to be static as they are in the same file as your main().
To call a method, just use the method name with parentheses, eg user();.
=====
"I'm currently trying to sort out your code and thought I'd whip this up quickly for your benefit. (It's your idea re-written my way)."
Hope this helps for now.
package oldMcDonald;
import javax.swing.JOptionPane;
public class MyAttempt {
public static void main(String[] args) {
callFirstLine();
callEiEiO();
System.out.println("And on his farm he had a cow, E-I-E-I-O,");
System.out.println("With a moo-moo here and a moo-moo there");
System.out.println("Here a moo, there a moo,");
System.out.println("Everywhere a moo-moo.");
callFirstLine();
callEiEiO();
}
public static void callFirstLine(){
System.out.println("Old McDonald had a farm,");
}
public static void callEiEiO() {
String input = "";
do{
input = JOptionPane.showInputDialog("Please Enter 'EiEiO': ");
}while (!"EiEiO".equals(input));
System.out.println(input);
}
}
Harmelodic is incorrect and unfortunately teaching you bad practices.
A method does not have to be static in order to be called in the same class as your main, further to this NEVER EVER do work in your main method, it is horrifically bad practice, not doing work in your main resolves the issue of having to have all static methods.
package oldMcDonald;
import javax.swing.JOptionPane;
public class MyAttempt {
public static void main(String[] args) {
MyAttempt matt = new MyAttempt();
matt.run();
}
public void run(){
callFirstLine();
callEiEiO();
System.out.println("And on his farm he had a cow, E-I-E-I-O,");
System.out.println("With a moo-moo here and a moo-moo there");
System.out.println("Here a moo, there a moo,");
System.out.println("Everywhere a moo-moo.");
callFirstLine();
callEiEiO();
}
public svoid callFirstLine(){
System.out.println("Old McDonald had a farm,");
}
public void callEiEiO() {
String input = "";
do{
input = JOptionPane.showInputDialog("Please Enter 'EiEiO': ");
}while (!"EiEiO".equals(input));
System.out.println(input);
}
}