ChatBot return bug - java

I'm working on a Chat Bot project, and I'm almost done, other than the fact that whenever I enter an input, it returns multiple outputs depending on the length of the input X.
Here is the source code:
import java.util.*;
public class ChatBot
{
public static String getResponse(String value)
{
Scanner input = new Scanner (System.in);
String X = longestWord(value);
if (value.contains("you"))
{
return "I'm not important. Let's talk about you instead.";
}
else if (X.length() <= 3)
{
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
else if (X.length() == 4)
{
return "Tell me more about " + X;
}
else if (X.length() == 5)
{
return "Why do you think " + X + " is important?";
}
return "Now we are getting somewhere. How does " + X + " affect you the most?";
}
private static String longestWord(String value){
Scanner input = new Scanner (value);
String longest = new String();
"".equals(longest);
while (input.hasNext())
{
String temp = input.next();
if(temp.length() > longest.length())
{
longest = temp;
}
}
return longest;
}
}
This is for testing the Chat Bot:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.next();
}
}
}
I am also trying to modify the Bot so it counts the number of times it has responded; and also modify it so it randomly returns a random response depending on the length of the input. Any help will be much appreciated. Thank You!

You are using the Scanner.next method which only returns the next word in the string. So if you input a string with multiple words, your bot will respond to each of them.
You can use Scanner.nextLine() to get the entire input string, instead of only 1 word.
To count the number of times your bot has responded, you can create a field in the bot class:
private int responseCount = 0;
Then if you change yout getResponse method from a static method to an instance method, you can update this value from this method:
public String getResponse(String value)
{
String X = longestWord(value); //Your longestWord should also not be static.
this.responseCount++;
if (value.contains("you"))
{
...

Regarding counting the responses, just modify your main method:
import java.util.Scanner;
public class Test {
public static void main (String [ ] args)
{
int numberOfResponses = 1;
Scanner input = new Scanner (System.in);
ChatBot e = new ChatBot();
String prompt = "What would you like to talk about?";
System.out.println(prompt);
String userInput;
userInput = input.next();
while (!userInput.equals("Goodbye"))
{
System.out.println(e.getResponse(userInput));
userInput = input.nextLine();
numberOfResponses++;
}
input.close();
System.out.println(numberOfResponses);
}
}
If I have the time I will edit my post in a few minutes to check your problem regarding the double appearences of a response. You also forgot to close the Scanner.
EDIT: It actually happens because scanner has as a default the delimiter set to be on whitespace. so if you input a text with a whitespace, the while loop runs twice for one user input. Just use the nextLine() command.
Why is this code:
Scanner input = new Scanner (System.in);
In your getResponse method? Its not used at all. Take a closer look at your methods as they are holding some strange code.

Related

How to repeat a question to a user until while loop condition is false?

I'm bulding a console application where I am trying to force a user to enter an int as a possible answer to a question otherwise the same question is repeated to the user.Thus, the user cannot move on without entering the proper data type.
below is my sample code.
Scanner scanner = new Scanner(System.in);
int userInput = 0;
do {
AskQuestion();
if(scanner.hasNextInt()) {
userInput = scanner.nextInt();
}
}
while(!scanner.hasNextInt()) ;
While I know this can be done in C#, I'm not exactly sure how to do it in java without getting stuck in an infinite loop. How do I get my code to do what I want to do? Please help!
You can use something like this. It'a a pretty simple flag combined with the use of the Scanner class.
boolean flag = false;
int val = 0;
while(!flag){
System.out.println("Something");
if(sc.hasNext()){
if(sc.hasNextInt()){
val = sc.nextInt();
flag = true;
}
else{
sc.next();
}
}
}
Try this:
Scanner scanner = new Scanner(System.in);
int userInput;
while(true) {
AskQuestion();
if (scanner.hasNextInt()) {
userInput = scanner.nextInt();
break;
}
scanner.next(); // consume non-int token
}
Another alternative which utilizes the Scanner#nextLine() method along with the String#matches() method and a small Regular Expression (RegEx) to ensure that the supplied string does indeed contain all numerical digits:
Scanner scanner = new Scanner(System.in);
String userInput = "";
int desiredINT = 0; // Default value.
while (desiredINT == 0) {
AskQuestion();
userInput = scanner.nextLine();
if (userInput.matches("\\d+")) {
desiredINT = Integer.parseInt(userInput);
if (desiredINT < 1 || desiredINT > 120) {
System.out.println("Invalid Input! The age supplied is not "
+ "likely! Enter a valid Age!");
desiredINT = 0;
}
}
else {
System.out.println("Invalid Input! You must supply an Integer "
+ "value! Try Again...");
}
}
System.out.println("Your age is: --> " + desiredINT);
And the AskQuestion() method:
private void AskQuestion() {
System.out.println("How old are you?");
}
This is nice and short one
Scanner scanner = new Scanner(System.in);
do askQuestion();
while(!scanner.nextLine().trim().matches("[\\d]+"));
Tell me if you like it
Note it just tell you if number was an int , and keeps repeating if not, but doesn't give you that int back , tell me if you need that, i shall find a way
My solution might be a bit bloated, but I hope it's nice and clear what's going on. Please do let me know how it can be simplified!
import java.util.Scanner; // Import the Scanner class
class Main {public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String unit;
// unit selector
while (true) {
System.out.println("Did you measure ion feet or meters? Type 'meters' or 'feet': ");
String isUnit = myObj.nextLine();
if (isUnit.equals("feet") || (isUnit.equals("meters"))) {
unit = isUnit;
break;
} else {
System.out.println("Please enter either 'meters' or 'feet'.");
}
}
System.out.println("Use selected " + unit);
}

Java Scanner delimiter and System.in

I have some problem when I ask the user to input some numbers and then I want to process them. Look at the code below please.
To make this program works properly I need to input two commas at the end and then it's ok. If I dont put 2 commas at the and then program doesnt want to finish or I get an error.
Can anyone help me with this? What should I do not to input those commas at the end
package com.kurs;
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
String gd = "4,5, 6, 85";
Scanner s = new Scanner(System.in).useDelimiter(", *");
System.out.println("Input some numbers");
System.out.println("delimiter to; " + s.delimiter());
int sum = 0;
while (s.hasNextInt()) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
s.close();
System.exit(0);
}
}
Your program hangs in s.hasNextInt().
From the documentation of Scanner class:
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input.
In a few words, scanner is simply waiting for more input after the last integer, cause it needs to find your delimiter in the form of the regular expression ", *" to decide that the last integer is fully typed.
You can read more about your problem in this discussion:
Link to the discussion on stackoverflow
To solve such problem, you may change your program to read the whole input string and then split it with String.split() method. Try to use something like this:
import java.util.Scanner;
public class NumberFromUser {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] tokens = sc.nextLine().split(", *");
int sum = 0;
for (String token : tokens) {
sum += Integer.valueOf(token);
}
System.out.println(sum);
}
}
Try allowing end of line to be a delimiter too:
Scanner s = new Scanner(System.in).useDelimiter(", *|[\r\n]+");
I changed your solution a bit and probably mine isn't the best one, but it seems to work:
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
int sum = 0;
if (s.hasNextLine()) {
// Remove all blank spaces
final String line = s.nextLine().replaceAll("\\s","");
// split into a list
final List<String> listNumbers = Arrays.asList(line.split(","));
for (String str : listNumbers) {
if (str != null && !str.equals("")) {
final Integer number = Integer.parseInt(str);
sum = sum + number;
}
}
}
System.out.println(sum);
look you can do some thing like this mmm.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Input some numbers");
System.out.println("When did you to finish and get the total sum enter ,, and go");
boolean flag = true;
int sum = 0;
while (s.hasNextInt() && flag) {
int d = s.nextInt();
sum = sum + d;
}
System.out.println(sum);
}

Deviding strings and integers of user input

I'm new to coding. I want to try out a few things using java with eclipse. In this programm the user should be able to use a few commands. For example a command called "add".
So when the user is typing "add 15 -200" the programm should call the add method and give it those to parameters. Sadly I have no idea how to properly read the integers and give them the "add" method. I just don't see how to devide the "add" string from the integers. Please help! Thanks in advance!
Take care
import java.util.Scanner;
public final class Test {
private static boolean quit = false;
private static final String PROMPT = "prompt> ";
int add( int i, int j) {
int result = i + j;
System.out.println(result);
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(!quit) {
System.out.print(PROMPT);
String input = scanner.nextLine().toLowerCase();
if(input.trim().equals("help") || input.trim().equals("h")) {
System.out.println("Try one of the following commands: ");
System.out.println("add n1 n2 : adds n1 to n2");
System.out.println("quit : quits the programm");
} else if(input.trim().equals("quit") || input.trim().equals("q")) {
quit = true;
} else if(input.equals("add ")) {;
}
}
}
}
that's my code so far. As you can see the last else if statement is empty because I have no idea how to sepperate strings with integers.

How to make my code accepts an input

I would just like to ask on how can I make my code to just get the input instead of declaring it? Here's my program. I want to input different atomic numbers and not just "37" like what's in my code. Don't mind my comments, it's in my native language. Thanks!
public class ElectConfi {
public static void main(String s[]) {
int atomicNumber = 37;
String electronConfiguration = getElectronConfiguration(atomicNumber);
System.out.println(electronConfiguration);
}
public static String getElectronConfiguration(int atomicNumber) {
int[] config = new int[20]; //dito nag store ng number of elec. in each of the 20
orbitals.
String[] orbitals = {"1s^", "2s^", "2p^", "3s^", "3p^", "4s^", "3d^", "4p^", "5s^",
"4d^", "5p^", "6s^", "4f^", "5d^", "6p^", "7s^", "5f^", "6d^", "7p^", "8s^"};
//Names of the orbitals
String result="";
for(int i=0;i<20;i++) //dito ung i represents the orbital and tapos ung j
represents ng electrons
{
for(int j=0;(getMax(i)>j)&&(atomicNumber>0);j++,atomicNumber--) //if atomic
number > 0 and ung orbital ay kaya pa magsupport ng more electrons, add
electron to orbital ie increment configuration by 1
{
config[i]+=1;
}
if(config[i]!=0) //d2 nagche-check to prevent it printing empty
orbitals
result+=orbitals[i]+config[i]+" "; //orbital name and configuration
correspond to each other
}
return result;
}
public static int getMax(int x) //returns the number of max. supported electrons by each
orbital. for eg. x=0 ie 1s supports 2 electrons
{
if(x==0||x==1||x==3||x==5||x==8||x==11||x==15||x==19)
return 2;
else if(x==2||x==4||x==7||x==10||x==14||x==18)
return 6;
else if(x==6||x==9||x==13||x==17)
return 10;
else
return 14;
}
}
You can use either a Scanner or BufferedReader and get the user input
Using Scanner
Scanner scanner = new Scanner(System.in);
System.out.println("Please input atomic number");
int atomicNumber = scanner.nextInt();
Using BufferedReader
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int atomicNumber = Integer.parseInt(reader.readLine());
public static String getElectronConfiguration(int atomicNumber) {}
This method accepting any int value and will return String result. so you only need to provide different number as input. There is no change required in this method.
How to provide different inputs?
You can use Scanner to do that.
Scanner scanner = new Scanner(System.in);
System.out.println("Please input atomic number");
int atomicNumber = scanner.nextInt();
Now call your method
String electronConfiguration = getElectronConfiguration(atomicNumber);
What are the other ways?
You can define set of values for atomicNumber in your code and you can run those in a loop
You can get input from command line arguments by doing below :
Scanner scanner = new Scanner(System.in);
String inputLine = scanner.nextLine(); //get entire line
//or
int inputInt= scanner.nextInt();//get an integer
Check java.util.Scaner api for more info - http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
Hope this helps!
You can get the user input from a command line argument:
public static void main(String s[]) {
if (s.length == 0) {
// Print usage instructions
} else {
int atomicNumber = Integer.parseInt(s[0]);
// rest of program
}
}

Scanner only reading first set of input

This is a code I have developed to separate inputs by the block (when a space is reached):
import java.util.Scanner;
public class Single {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Three Numbers:");
String numbers = in.next();
int length = numbers.length();
System.out.println(length);
int sub = length - length;
System.out.println(sub);
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
System.out.println(getNumber(numbers, length, sub));
}
public static double getNumber(String numbers, int length, int sub){
boolean gotNumber = false;
String currentString = null;
while (gotNumber == false){
if (numbers.substring(sub, sub + 1) == " "){
sub = sub + 1;
gotNumber = true;
} else {
currentString = currentString + numbers.substring(sub, sub);
sub = sub + 1;
}
}
return Double.parseDouble(currentString);
}
}
However, it only reads the first set for the string, and ignores the rest.
How can I fix this?
The problem is here. You should replace this line
String numbers = in.next();
with this line
String numbers = in.nextLine();
because, next() can read the input only till the first space while nextLine() can read input till the newline character. For more info check this link.
If I understand the question correctly, you are only calling in.next() once. If you want to have it process the input over and over again you want a loop until you don't have any more input.
while (in.hasNext()) {
//do number processing in here
}
Hope this helps!

Categories