The user enters an expression. Suppose user entered the following as input:
new y java.util.ArrayList int:5
i have successfully tokenized the string and stored it into different locations of my String array. next thing i want to do is that i should check whats on the index and do things according as mentioned in the above input for reflection. Am stuck how to do it. here is my code so far
public static void handling_input()
{
System.out.println("Welcome To Java Command Prompt: ");
aLine = null;
try
{
System.out.println("Enter The Command Line Expression: ") ;
keyboard = new BufferedReader(new InputStreamReader(System.in));
aLine = keyboard.readLine();
st = new StringTokenizer(aLine);
dt = new StringTokenizer(aLine);
}
catch (IOException ex)
{
System.out.println("Error reading input!");
}
}
public static void storing_tokens()
{
int counter =0;
while(st.hasMoreTokens())
{
counter++;
st.nextToken();
}
int i=0;
expression_keeper= new String[counter];
do
{
expression_keeper[i] = dt.nextToken().toString();
i++;
}while(dt.hasMoreTokens());
}
public static void token_classification()
{
for(int i=0; i<expression_keeper.length; i++)
{
if(expression_keeper[0].equalsIgnoreCase("new"))
{
}
else
if(expression_keeper[0].equalsIgnoreCase("call"))
{
}
else
if(expression_keeper[0].equalsIgnoreCase("print"))
{
}
else
{
System.out.println("Invalid Script!");
}
}
}
}
Inside this if condition:
if(expression_keeper[0].equalsIgnoreCase("new"))
{
}
i want to create the specified class,its object and assign values to the modifiers mentioned!
It is unclear to me what your input string tokens really mean. Is "java.util.ArrayList" the type for "y" and should it have an initial size of 5 units? Or should the first element be an integer of 5?
In the past I have found writing my own syntax tokenizer and parser a complicated thing to do. Even in simple cases I have often found that using something like JavaCC was easier in the long run.
By specifying your syntax formally you give much but structure to your code and it's debuggability. And then as said elsewhere use introspection to do the creation. The packages to do this are in java.lang.reflect.
Related
I want to take input from user and then want to find is it Integer, float or something else. Till now I am using Scanner class for that. Like Scanner scan1=new Scanner(System.in);
String st= scan1.next(); and then I am trying to parse that input (st) in int and float respectively. But with this approach I am not able to satisfy the "else" condition. i.e. when input is neither string, int nor float.
Below is the code I tried :-
public String checkInput() {
String statement = "This input is of type ";
String inputType;
Scanner scan1 = new Scanner(System.in);
String st = scan1.next();
scan1.close();
inputType = st.getClass().getSimpleName();
try {
Float numFloat = Float.parseFloat(st);
inputType = numFloat.getClass().getSimpleName();
} catch (NumberFormatException e) {
}
try {
Integer numInt = Integer.parseInt(st);
inputType = numInt.getClass().getSimpleName();
} catch (NumberFormatException e) {
}
return statement + inputType;
}
here I am not able to decide how should I place else condition to check the input is neither string,float nor integer.
Here's how I would restructure your code. I'll explain the changes below:
private static final String STATEMENT = "This input is of type ";
public static String checkInput(Scanner scanner) {
if (scanner.hasNextFloat()) {
return STATEMENT + Float.class.getSimpleName();
else if (scanner.hasNextInt()) {
return STATEMENT + Integer.class.getSimpleName();
}
return STATEMENT + "UNKNOWN";
}
First, we pulled statement out into a constant, since it's not being changed.
Second, we pass the Scanner in as a parameter, rather than constructing a new one. There are a number of reasons to prefer this, but the principle one is that you should avoid creating multiple Scanner instances reading from System.in - generally you'll create such a Scanner in your main() method and pass it off to the methods and classes that need to use it.
Next, rather than reading from the scanner directly, we use the has*() methods to inspect the scanner's state without advancing it. This changes the semantics of checkInput(), because when it returns the input being inspected is still in the scanner, but that's more consistent with a method named check...() - it should inspect, not change state. Because your implementation calls .next() you lose the actual provided input, which is presumably undesirable.
Finally, we return from inside each block, rather than setting a temporary inputType variable and returning it at the end.
Your main() method might now look like this:
public static void main(String[] args) {
// using try-with-resources so we don't have to call .close()
try (Scanner scanner = new Scanner(System.in)) {
System.out.println(checkInput(scanner));
String input = scanner.next(); // this actually advances the scanner
System.out.println("You input: " + input);
}
}
Taking it further, you might prefer to have checkInput() return a Class<?> rather than a String, and then construct your statement separately. This would allow you to handle the inputs differently. For example:
public static Class<?> inputType(Scanner scanner) {
if (scanner.hasNextFloat()) {
return Float.class;
else if (scanner.hasNextInt()) {
return Integer.class;
}
// add other types as needed
return String.class;
}
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
Class<?> inputType = inputType(scanner);
String input = scanner.next();
System.out.println("You input: " + input);
if (inputType.equals(Integer.class)) {
System.out.prinln("That's a valid integer!");
}
}
}
All that said, we're very much reinventing the wheel here. The "right" way to use Scanner is to use the typed methods directly - e.g.:
if (scanner.hasNextInt()) {
int value = scanner.nextInt();
}
This avoids needing to do any manual type checking or similar busywork - just let Scanner do the validation for you.
import java.util.Scanner;
class sexy
{
void even(String s)
{
for( int i=0;i<s.length();i++)
{
if((i==0) ||(i%2==0))
{
System.out.print(s.charAt(i));
}
}
}
void odd(String s)
{
for( int i=0;i<s.length() ; i++)
{
if(i%2!=0)
{
System.out.print(s.charAt(i));
}
}
}
}
class sassy
{
public static void main(String args[])
{
sexy se = new sexy();
Scanner scan = new Scanner(System.in);
int i=0,p;
p=scan.nextInt();
scan.nextLine();
String s;
while(i<p)
{
s = scan.nextLine();
se.even(s);
System.out.print(" ");
se.odd(s);
i++;
}
scan.close();
}
}
Now here i am able to take multiple inputs..and after every input i have to perform the operation on that particular input.. But I want to take multiple inputs at first and then perform the same operation on all the inputs using minimum variables..(if possible just one)
Well, it looks like you would either need a string array or a string arraylist.
You would use a string array if you knew how many inputs you would get, and an arraylist if you don't know how many inputs would be put in.
The code would look something like this:
ArrayList<String> lines = new ArrayList<>();
To put the values in, you would use lines.put(), and then lines.get(i) in your for loop to get values back out.
So to use it in your program, just add all the lines that the user inputs into the arraylist, and then traverse the arraylist to do the even and odd functions.
Good luck!
This essentially is a small code I'm writting for practice that requires me to use StringTokenizer. I've done the same kind of programs before , but now when I store the strings in an array and try to print them it show's a null pointer exception. Any help?
import java.util.*;
public class board1
{
String key;
String m[];
//function to accept the sentence
void getsent()
{
Scanner in=new Scanner(System.in);
System.out.println("Enter a sentence terminated by'.' or '?'");
String take=in.nextLine();
StringTokenizer taken=new StringTokenizer(take);
int numtokens=taken.countTokens();
String m[]=new String[numtokens];
for(int i=0;i<m.length;i++)
{
m[i]=taken.nextToken();
}
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]);
}
}
// function to display
void display()
{
System.out.println("The words seperately right now are:");
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]+"\t");
System.out.println();
}
}
// main to get functions
public static void main(String args[])
{
board1 ob= new board1();
ob.getsent();
ob.display();
}
}
You're shadowing the variable m. Replace
String m[] = new String[numtokens];
with
m = new String[numTokens];
I think because you are shading properties. You have an array called m into which you are putting tokens in getSent, but display is using the m array defined in the class to which you haven't added anything.
Print out the size of m in display, this will show you that you are not adding anything to the property called m.
I know that the whole point of OOP is so that code doesnt have to be rewritten.
I have a class (lets call it E) and a main class (lets call it main) with a main method that validates some inputs and then feeds them into class E (which encrypts the inpts) to get a result to output to the user (the encrypted input).
Now I am writing a subclass from the perspective that I was someone else improving the program. I have a subclass of the encryption class which uses similar principles but an improved method of encryption (lets call it class ImprovedE).
As the new developer I am pretending to be, would I just write the subclass and then rewrite the main method from the original program to feed the inputs into Improved E instead of E?
I know I can't override the main method but I dont think I should be changing the original code either. Any help would be appreaciated.
Heres the code (EDIT), that i forgot to add.
package encryption;
import java.util.Scanner;
import static encryption.encryptionChoice.*;
public class main {
//These are all the reusable variables created to temporarily store information before pushing it to the Encryption class
//This is a simple starter message to inform the user of how to use the program
private String initialDisplayInformation = "Message Encryption/Decryption program for use with letters and spaces only. \nPress any key to continue...";
//These are the "scope" input and output variables visible to the user
private String inputString;
private String outputString;
//This creates the encryption class
private Encryption myEncryption = new Encryption();
//These are used to later create two loops that only break when an acceptable input has been input for the values
private Boolean inputValidated = false;
private Boolean cypherValidated = false;
private Boolean choiceValidated = false;
private void initialInfo() {
//These 2 lines make the user have to hit any key before continuing after reading the info
System.out.println(initialDisplayInformation);
String pressAnyKey = new Scanner(System.in).nextLine();
}
private void inputValidation(){
//This loop attepts to validate the message input and uses the boolean returned fromthe Encryption.setInput class to see the success
//It prints a detailed error and repeats if unsuccessful
do {
System.out.println("\nEnter your message: ");
try {
inputValidated = myEncryption.setInput(new Scanner(System.in).nextLine());
} catch(NotACharacterException e) {
System.out.println(e.errorMessage());
}
} while(!inputValidated);
}
private void cypherValidation(){
//This repeats the exact process as the previous loop, but for the cypher length
do {
System.out.println("\nEnter your cypher length (How much the message will be/was offset by: ");
try {
cypherValidated = myEncryption.setCypher(new Scanner(System.in).nextInt());
if(!cypherValidated) {
System.out.println("That is not an acceptable integer, please try again... ");
}
}catch(Exception e){
System.out.println("That is not a valid input, please try again... ");
}
} while(!cypherValidated);
}
private void encryptionDecision(){
do {
System.out.println("\nWould you like to 1)Encrypt 2)Decrypt the message: ");
String choiceString = new Scanner(System.in).nextLine();
encryptionChoice choice = ERROR;
if(choiceString.equalsIgnoreCase("Encrypt")|| choiceString.equalsIgnoreCase("1")){
choice = ENCRYPT;
}
if(choiceString.equalsIgnoreCase("Decrypt") || choiceString.equalsIgnoreCase("2")){
choice = DECRYPT;
}
try {
System.out.println(myEncryption.getInput());
System.out.println(myEncryption.EncryptionDecryption(choice));
choiceValidated = true;
} catch(IllegalArgumentException e) {
System.out.println("Please only enter: Encrypt, Decrypt, 1 or 2. Please try again... ");
}
} while(!choiceValidated);
}
public static void main(String[] args) {
boolean runProgram = true;
while(runProgram){
main thread = new main();
thread.initialInfo();
thread.inputValidation();
thread.cypherValidation();
thread.encryptionDecision();
runProgram=false;
Scanner keyboard = new Scanner(System.in);
System.out.println("\nPress 'r' to restart or 'enter' to exit");
if(new Scanner(System.in).nextLine().equals("r")) {
runProgram=true;
}
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package encryption;
/**
*
* #author Alex
*/
public class SingleKeywordEncryption extends Encryption {
protected String keywordString;
protected Integer getKeywordCypher(String keyword, Integer term){
Character letterInKeyword = 0;
Integer cypherLength;
if(term<keyword.length()){
letterInKeyword = keyword.charAt(term);
}
else if(term>=keyword.length()) {
letterInKeyword = keyword.charAt(term%keyword.length());
}
cypherLength = termOf(letterInKeyword);
return cypherLength;
}
#Override
public String EncryptionDecryption(encryptionChoice choice) {
String outputString = "";
switch(choice){
case ENCRYPT:
for(int i=0;i<inputString.length();i++) {
outputString = outputString + letterOf(termOf(inputString.charAt(i)) + getKeywordCypher(keywordString, i));
}
break;
case DECRYPT:
for(int i=0;i<inputString.length();i++) {
outputString = outputString + letterOf(termOf(inputString.charAt(i)) - getKeywordCypher(keywordString, i));
}
break;
default:
throw new IllegalArgumentException();
};
return outputString;
}
}
package encryption;//Includes the class int he encryption package of classes for my project
//This creates a class called Encryption where the majority of my project is stored
public class Encryption {
//These create the variables needed throughout the class
//This is final so that it is immutable and usable in all the methods
//I made it a Character array to save memory use and to allow simpler comparison methods in other areas of the program
private final Character[] alphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
//These are private for good coding practice, so that they can only be modified from within the class
private Integer cypher;
protected String inputString;
public String getInput() {
return inputString;
}
//This class simply validates and saves the cypher length to its variable and returns a boolean of its success
public boolean setCypher(Integer cypherToAdd) {
while(cypherToAdd>26 || cypherToAdd<0){
return false;
}
//It tries to save it and returns false if it cannot be saved as an integer
try {
cypher = cypherToAdd;
}
catch (Exception e) {
return false;
}
return true;
}
//This class validates andsaves the input to its variable and removes any whitespace from it
public boolean setInput(String inputToAdd) throws NotACharacterException {
//This uses replaceAll to remove whitespace and saves the object that is rejurned from the method to String input
String input = inputToAdd.replaceAll("\\s","");
//This iterates through every character in the input and checks that it is a letter
for (int term=0; term<input.length();term++) {
//If a term is not a letter, it throws the custom NotACharacterException and passes information of which non-letter character caused it
if(!Character.isLetter(input.charAt(term))){
throw new NotACharacterException("'" + String.valueOf(input.charAt(term)) + "' This character can not be used in this program...\nStick to letters and spaces only please.");
}
}
inputString = input;
return true;
}
//This class returns the term of a passed letter in the alphabet
protected int termOf(Character letter) {
//The term variable to be returned is initialised immediately
int term =0;
//The for loop iterates through every letter in the alphabet and compares it with the letter passed to the method to find its term
for (int currentTerm=0; currentTerm<alphabet.length;currentTerm++) {
//When the letters match, the term is returned to where the method is called
if(letter.toLowerCase(letter)==alphabet[currentTerm]){
term = currentTerm;
}
}
return term;
}
//This class returns the letter of a passed term in the alphabet
protected Character letterOf(int inputTerm) {
if(inputTerm>25){
return alphabet[inputTerm-26];
} else if (inputTerm<0) {
return alphabet[inputTerm+26];
}
else {
//It recieves the character by gathering the character in the inputTerm's place in the array, and returns it
return alphabet[inputTerm];
}
}
public String EncryptionDecryption(encryptionChoice choice){
String outputString = "";
switch(choice){
case ENCRYPT:
for(int i=0;i<inputString.length();i++) {
outputString = outputString + letterOf(termOf(inputString.charAt(i))+ cypher);
}
break;
case DECRYPT:
for(int i=0;i<inputString.length();i++) {
outputString = outputString + letterOf(termOf(inputString.charAt(i))- cypher);
}
break;
default:
throw new IllegalArgumentException();
};
return outputString;
}
}
No matter what, you will have to change something somewhere in your code so that the main uses your ImprovedE class instead of the E class. Otherwise, the program will not know by itself if you want to use E or ImprovedE.
If you will not use the encryption method in E and will always use ImprovedE, it would be better to include all the methods from E into ImprovedE. This way, you will not have to make any decisions on which class to use.
If you still want to be able to switch between the two classes, I recommend using the Strategy design pattern. You would put any methods shared between the two classes (such as termOf(Character letter), letterOf(int inputTerm) and setInput(String inputToAdd)) in a class accessible by both encyption strategy, and you would have two ConcreteStrategy: E and ImprovedE.
This way, you can switch between the two strategies quickly, just by changing the ConcreteStrategy (In your case, if you want to use the old or the new encryption method). You could also prompt the user to know which encryption method he wants if that's a valid use case.
I know that the whole point of OOP is so that code doesnt have to be rewritten...
Actually, the purpose of OOP is to make the organization of code easier to conceptualize. extends is considered by many to be an antipattern.
Consider using implements on an abstract base class to define an interface and letting future devs worry about 'improvements'.
In Java, the main method is static, which means it cannot be overriden. This is by design, but not necessarily optimal design. There is no universal reason why this could not be done in principle, but Java does not do it.
The thing is: you should not have to need this in the first place. Your former developer mixed responsabilities by putting all of these encryption methods and state information in the same class which represents the computation itself: your main class.
So, what you have to do is actually decouple these things because the main method has to very small and narrow-purposed. When this happens, it will not feel like there is so much repetition in place. If there is, there is always more room for refactoring.
I am very new to Java and writing this program to shuffle words and fix the suffle words. The following is my program. After I call mix(), I would like to be able to assign the output of word to team array within main.
For some reason, I can call mix() it works but I cannot access word which is in the shuffle function. Since I am in main and all these function within main, I thought I can access the variables. Any ideas what I am missing here?
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Project2
{
public static void main(String[] args)
{
System.out.println("Select an item from below: \n");
System.out.println("(1) Mix");
System.out.println("(2) Solve");
System.out.println("(3) Quit");
int input;
Scanner scan= new Scanner(System.in);
input = scan.nextInt();
//System.out.println(input);
if(input==1) {
mix();
System.out.println(word);
char team[]=word.toCharArray();
for(int i=0;i<team.length;i++){
System.out.println("Data at ["+i+"]="+team[i]);
}
}
else{
System.out.println("this is exit");
}
}
static void mix()
{
String [] lines=new String[1000];//Enough lines.
int counter=0;
try{
File file = new File("input.txt");//The path of the File
FileReader fileReader1 = new FileReader(file);
BufferedReader buffer = new BufferedReader(fileReader1);
boolean flag=true;
while(true){
try{
lines[counter]=buffer.readLine();//Store a line in the array.
if(lines[counter]==null){//If there isn't any more lines.
buffer.close();
fileReader1.close();
break;//Stop reading and close the readers.
}
//number of lines in the file
//lines is the array that holds the line info
counter++;
}catch(Exception ex){
break;
}
}
}catch(FileNotFoundException ex){
System.out.println("File not found.");
}catch(IOException ex){
System.out.println("Exception ocurred.");
}
int pick;
Random rand = new Random();
pick = rand.nextInt(counter ) + 0;
System.out.println(lines[pick]);
///scramble the word
shuffle(lines[pick]);
}
static void shuffle(String input){
List<Character> characters = new ArrayList<Character>();
for(char c:input.toCharArray()){
characters.add(c);
}
StringBuilder output = new StringBuilder(input.length());
while(characters.size()!=0){
int randPicker = (int)(Math.random()*characters.size());
output.append(characters.remove(randPicker));
}
String word=output.toString();
}
}
Return string value from shuffle() method using return statement:
static String shuffle(String input) {
// . . .
return output.toString();
}
...and then use it in mix:
String word = shuffle(lines[pick]);
But it is better to read basic java tutorials before programming.
In Java, variables cannot be seen outside of the method they are initialized in. For example, if I declare int foo = 3; in main, and then I try to access foo from another method, it won't work. From the point of view of another method, foo does not even exist!
The way to pass variable between methods is with the return <variable> statement. Once the program reaches a return statement, the method will quit, and the value after the return (perhaps foo) will be returned to the caller method. However, you must say that the method returns a variable (and say what type is is) when you declare that method (just like you need to say void when the method does not return anything!).
public static void main(String[] args){
int foo = 2;
double(foo); //This will double foo, but the new doubled value will not be accessible
int twoFoo = double(foo); //Now the doubled value of foo is returned and assigned to the variable twoFoo
}
private static int double(int foo){//Notice the 'int' after 'static'. This tells the program that method double returns an int.
//Also, even though this variable is named foo, it is not the same foo
return foo*2;
}
Alternatively, you could use instance variable to have variables that are accessible by all the methods in your class, but if you're new to Java, you should probably avoid these until you start learning the basics of object-oriented programming.
Hope this helps!
-BritKnight