patternjavaMinor
Decides the mechanism of organic chemical reactions based on user input
Viewed 0 times
decidestheuserorganicinputmechanismbasedchemicalreactions
Problem
I'm new to programming, and I would appreciate any constructive criticism on my code and if there may be a more efficient way to code this.
```
import java.util.Scanner;
/**
* This program will decide what mechanism a reaction will undergo given information about the reactants.
* I will also include a mechanism to give a rudimentary explanation of the decision making process to
* get the reaction mechanism.
* I can make all of these Case Switches so I can account for misspellings and such
*/
public class mechanism
{
public static void main(String[] args)
{
System.out.println("Hello, this program is designed to figure out what mechanism a reaction will under go.");
//The decision tree will be a series of if-else statements. If I find a better method, I will use that
//I will add the Switch for the different types of reactions
Scanner keyboard = new Scanner(System.in);
String Start = "y";
String functional = "unassigned";//Defines if the functional roup is primary secondary or tertiary
String Base = "unassigned";//Defines the strength of the base if needed
String Polar = "unassigned";//Defines if the reactant is polarizable
String Solvent = "unassigned"; //Defines if the solvent is protic or aprotic
String Size = "unassigned";//Defines the Size of a Base
String Heat = "unassigned";//This is for whether or not it is heated
String Tetra = "unassigned";//Defines if a reaction can be tetra substituted
String Alk = "unassigned";// Alkane or alkene
int error = 0; //Defines error state
while (Start.equalsIgnoreCase("y")) {
System.out.println("Enter alkane to continue");
Alk = keyboard.next();
switch (Alk){
case "alkane":System.out.println("Is the reactant soluble in the solvent? Answer in y or n.");
String Solubility = keyboard.next(); //Defines if the reactant is soluble in the solvent
switch(Solubility)
{
```
import java.util.Scanner;
/**
* This program will decide what mechanism a reaction will undergo given information about the reactants.
* I will also include a mechanism to give a rudimentary explanation of the decision making process to
* get the reaction mechanism.
* I can make all of these Case Switches so I can account for misspellings and such
*/
public class mechanism
{
public static void main(String[] args)
{
System.out.println("Hello, this program is designed to figure out what mechanism a reaction will under go.");
//The decision tree will be a series of if-else statements. If I find a better method, I will use that
//I will add the Switch for the different types of reactions
Scanner keyboard = new Scanner(System.in);
String Start = "y";
String functional = "unassigned";//Defines if the functional roup is primary secondary or tertiary
String Base = "unassigned";//Defines the strength of the base if needed
String Polar = "unassigned";//Defines if the reactant is polarizable
String Solvent = "unassigned"; //Defines if the solvent is protic or aprotic
String Size = "unassigned";//Defines the Size of a Base
String Heat = "unassigned";//This is for whether or not it is heated
String Tetra = "unassigned";//Defines if a reaction can be tetra substituted
String Alk = "unassigned";// Alkane or alkene
int error = 0; //Defines error state
while (Start.equalsIgnoreCase("y")) {
System.out.println("Enter alkane to continue");
Alk = keyboard.next();
switch (Alk){
case "alkane":System.out.println("Is the reactant soluble in the solvent? Answer in y or n.");
String Solubility = keyboard.next(); //Defines if the reactant is soluble in the solvent
switch(Solubility)
{
Solution
First of all, you should pay attention to conventions such as capitalization and indentation. Class names should be
This decision tree appears to be an easy task. It turns out that doing it well is much more difficult than it seems. You'll see, from the suggested solution below, that a good solution isn't exactly obvious to beginners.
The problem with the naïve approach, whether using
You should, therefore, switch to a different strategy: data-directed programming. The behaviour should be primarily driven by a data structure — something that looks like this:
In a more elaborate program, this data structure might even be defined using xml, a yaml file, or maybe even be stored in a database.
Suggested solution
Define supporting classes to represent the questions, answers, and results. I also suggest defining helper functions
Then, you can write a
```
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
public class ReactionMechanism {
//////////////////////////////////////////////////////////////////////
private interface MenuItem {
}
private static class Menu implements MenuItem {
public final String question;
public final Answer[] answers;
public final String possibleAnswers;
public Menu(String question, Answer... answers) {
this.question = question;
this.answers = answers;
this.possibleAnswers = Arrays.stream(answers)
.map(a -> "\"" + a.choice + "\"")
.collect(Collectors.joining(" / "));
}
}
private static class Answer {
public final String choice;
public final MenuItem decision;
public Answer(String choice, MenuItem decision) {
this.choice = choice;
this.decision = decision;
}
}
private static class Result implements MenuItem {
public final String result;
public Result(String result) {
this.result = result;
}
public String toString() {
return this.result;
}
}
private static Menu q(String question, Answer... answers) {
return new Menu(question, answers);
}
private static Answer a(String choice, MenuItem decision) {
return new Answer(choice, decision);
}
private static Result result(String result) {
return new Result(result);
}
//////////////////////////////////////////////////////////////////////
private static final Menu ALKANE_REACTION_DECISION_TREE = q("What kind of hydrocarbon?",
a("alkane",
q("Is the reactant soluble?",
a("y", // soluble
q("Is the functional group attached to a primary, secondary, or tertiary carbon?",
a("p", // primary
q("All unimolecular reactions are ruled out, leaving E2 and Sn2.\n" +
"Is the reactant a strong base?",
a("y", result("The reaction undergoes E2")),
a("n", result("The reaction undergoes Sn2")))),
a("s", // secondary
q("No reactions have been ruled out.\n" +
"Is the reactant a strong base?",
a("y", // strong base
q("Is it a bulky base or a skinny base?",
a("b", result("The reaction undergoes E2")),
a("s", result("The reaction undergoes Sn2")))),
a("n", // not s
UpperCase; variable names should be lowerCase. And for deeply nested code like this, consistently correct indentation is absolutely essential!This decision tree appears to be an easy task. It turns out that doing it well is much more difficult than it seems. You'll see, from the suggested solution below, that a good solution isn't exactly obvious to beginners.
The problem with the naïve approach, whether using
if/else or switch, is that it results in a lot of code repetition. Basically, the solution doesn't scale well if the decision tree grows. It's tricky to ensure that every menu behaves consistently, because it's copy-and-pasted code. Furthermore, it's difficult to do proper error handling.You should, therefore, switch to a different strategy: data-directed programming. The behaviour should be primarily driven by a data structure — something that looks like this:
private static final Menu ALKANE_REACTION_DECISION_TREE = q("What kind of hydrocarbon?",
a("alkane",
q("Is the reactant soluble?",
a("y",
q("Is the functional group attached to a primary, secondary, or tertiary carbon?",
a("p",
q("All unimolecular reactions are ruled out, leaving E2 and Sn2.\n" +
"Is the reactant a strong base?",
a("y", result("The reaction undergoes E2")),
a("n", result("The reaction undergoes Sn2")))),
…In a more elaborate program, this data structure might even be defined using xml, a yaml file, or maybe even be stored in a database.
Suggested solution
Define supporting classes to represent the questions, answers, and results. I also suggest defining helper functions
q(), a(), and result(), respectively, to avoid writing the new keyword everywhere when defining the tree.Then, you can write a
menu() loop that navigates that tree structure based on the user input.```
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
public class ReactionMechanism {
//////////////////////////////////////////////////////////////////////
private interface MenuItem {
}
private static class Menu implements MenuItem {
public final String question;
public final Answer[] answers;
public final String possibleAnswers;
public Menu(String question, Answer... answers) {
this.question = question;
this.answers = answers;
this.possibleAnswers = Arrays.stream(answers)
.map(a -> "\"" + a.choice + "\"")
.collect(Collectors.joining(" / "));
}
}
private static class Answer {
public final String choice;
public final MenuItem decision;
public Answer(String choice, MenuItem decision) {
this.choice = choice;
this.decision = decision;
}
}
private static class Result implements MenuItem {
public final String result;
public Result(String result) {
this.result = result;
}
public String toString() {
return this.result;
}
}
private static Menu q(String question, Answer... answers) {
return new Menu(question, answers);
}
private static Answer a(String choice, MenuItem decision) {
return new Answer(choice, decision);
}
private static Result result(String result) {
return new Result(result);
}
//////////////////////////////////////////////////////////////////////
private static final Menu ALKANE_REACTION_DECISION_TREE = q("What kind of hydrocarbon?",
a("alkane",
q("Is the reactant soluble?",
a("y", // soluble
q("Is the functional group attached to a primary, secondary, or tertiary carbon?",
a("p", // primary
q("All unimolecular reactions are ruled out, leaving E2 and Sn2.\n" +
"Is the reactant a strong base?",
a("y", result("The reaction undergoes E2")),
a("n", result("The reaction undergoes Sn2")))),
a("s", // secondary
q("No reactions have been ruled out.\n" +
"Is the reactant a strong base?",
a("y", // strong base
q("Is it a bulky base or a skinny base?",
a("b", result("The reaction undergoes E2")),
a("s", result("The reaction undergoes Sn2")))),
a("n", // not s
Code Snippets
private static final Menu ALKANE_REACTION_DECISION_TREE = q("What kind of hydrocarbon?",
a("alkane",
q("Is the reactant soluble?",
a("y",
q("Is the functional group attached to a primary, secondary, or tertiary carbon?",
a("p",
q("All unimolecular reactions are ruled out, leaving E2 and Sn2.\n" +
"Is the reactant a strong base?",
a("y", result("The reaction undergoes E2")),
a("n", result("The reaction undergoes Sn2")))),
…import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
public class ReactionMechanism {
//////////////////////////////////////////////////////////////////////
private interface MenuItem {
}
private static class Menu implements MenuItem {
public final String question;
public final Answer[] answers;
public final String possibleAnswers;
public Menu(String question, Answer... answers) {
this.question = question;
this.answers = answers;
this.possibleAnswers = Arrays.stream(answers)
.map(a -> "\"" + a.choice + "\"")
.collect(Collectors.joining(" / "));
}
}
private static class Answer {
public final String choice;
public final MenuItem decision;
public Answer(String choice, MenuItem decision) {
this.choice = choice;
this.decision = decision;
}
}
private static class Result implements MenuItem {
public final String result;
public Result(String result) {
this.result = result;
}
public String toString() {
return this.result;
}
}
private static Menu q(String question, Answer... answers) {
return new Menu(question, answers);
}
private static Answer a(String choice, MenuItem decision) {
return new Answer(choice, decision);
}
private static Result result(String result) {
return new Result(result);
}
//////////////////////////////////////////////////////////////////////
private static final Menu ALKANE_REACTION_DECISION_TREE = q("What kind of hydrocarbon?",
a("alkane",
q("Is the reactant soluble?",
a("y", // soluble
q("Is the functional group attached to a primary, secondary, or tertiary carbon?",
a("p", // primary
q("All unimolecular reactions are ruled out, leaving E2 and Sn2.\n" +
"Is the reactant a strong base?",
a("y", result("The reaction undergoes E2")),
a("n", result("The reaction undergoes Sn2")))),
a("s", // secondary
q("No reactions have been ruled out.\n" +
"Is the reactant a strong base?",
a("y", // strong base
q("Is it a bulky base or a skinny base?",
a("b", result("The reaction undergoes E2")),
a("s", result("The reaction undergoes Sn2")))),
a("n", // not strong base
q("Is the reactant polarizable?",
a("y", resContext
StackExchange Code Review Q#126677, answer score: 5
Revisions (0)
No revisions yet.