I'm writing a program that can grade multiple choice exercises for a class.
I wanted to store each answer key as a String array, and then have the user enter a String (the name of the exercise) which would be able to summon the stored String array. From there I know how to compare the stored String to the user's inputs.
I just have no idea how to take the input String and use it to summon the stored String array. Any tips?
thanks!
Using individual arrays to store each answer is grossly inefficient. What you need is an object that can store values which can be referenced by a key and a Hashmap provides just that. Study the illustration below:
//Declare your hashmap:
Map <String, String> myAnswers = new HashMap<>();
/*
*Put the values you want
*The put method takes in two parameters, the key and the value.
*The key represents the name you want to call this element by.
*The value is the actual value (so to speak)
*/
myAnswers.put("firstQuestion", "Answer of firstQuestion");
myAnswers.put("secondQuestion", "Answer of secondQuestion");
myAnswers.put("thirdQuestion", "Answer of thirdQuestion");
//You can go on and on: key, value.. Just like we did up there.
If you need the value of any of these keys, just do something like this:
myAnswers.get(firstQuestion);
I hope this helps.. Merry coding!
There are many ways to do this, it kind of all depends on your code design, but in general you can retrieve specific positions of any String[] by using a simple for loop (assuming this is a long test quiz):
class Grades {
Grades grades = new Grades();
String [] test1 = {"A", "B", "A", "C"};
for (int i = o; i < test1.length; i++) {
//this will retrieve every grade at every array position in order for 0 to
however long the array is.
grades.get[i]
}
}
Related
So I'm going crazy with this one. This is for an assignment and can't seem to get this to work at all!!
I have the following HashMap:
HashMap<String, ArrayList<Team>> teams;
(Team being another class to obtain the details of the teams)
What I need to be able to do is get the List of teams for the Key(String) from the above HashMap, and assign the List to a local variable I have declared:
List<Team> results = teams.get(division);
But this is where I get stuck. I have no idea how I'm suppose to complete this task.
As a further note "division" is the Key used in the HashMap. The ArrayList is a list of teams that belong to the division.
I have tried the below, which does not compile at all. Really not sure how I can get this to work!!
public void recordResult(String division, String teamA, String teamB, int teamAScore, int teamBScore)
{
List<Team> results = teams.get(division);
for (String i : teams.keySet())
{
results = new ArrayList<Team>();
results.add();
}
}
**You can ignore the arguments after the "String division". These will be used later.
Iterate over the entrySet() of the Map. Now you can fetch each List for that specific key and proceed further. Something like:
for (Entry<String, ArrayList<Team>> entry : teams.entrySet()) {
// extract the value from the key using `teams.get(entry.getKey())`
// proceed further with the value obtained
}
So I'm trying retrieve specific substrings in values in a Hashmap constructed like this..
HashMap<ID, "Home > Recipe > Main Dish > Chicken > Chicken Breasts">
Which is passed from a different method that returns a HashMap
In above example, I need to retrieve Chicken.
Thus far, I have..
public static ArrayList<String> generalize() {
HashMap<String, String> items = new HashMap<>();
ArrayList<String> cats = new ArrayList<>();
items = RecSys.readInItemProfile("PATH", 0, 1);
for(String w : items.values()) {
cats.add(w);
}
for(String w : cats) {
int e = w.indexOf('>', 1 + w.indexOf('>', 1 + w.indexOf('>')));
String k = w.substring(e+1);
System.out.print(k);
e = 0;
}
System.out.println("k" + cats);
return cats;
}
Where I try to nullify String e for each iteration (I know it's redundant but it was just to test).
In my dataset, the first k-v pair is
3880=Home > Recipes > Main Dish > Pasta,
My output is
Pasta
Which is ok. If there are more than 3x ">", it'll return all following categories. Optimally it wouldn't do that, but it's ok if it does. However, further down the line, it (seemingly) randomly returns
Home > Recipe
Along with the rest of the data...
This happens at the 6th loop, I believe.
Any help is greatly appreciated..
Edit:
To clarify, I have a .csv file containing 3 columns, whereas 2 are used in this function (ID and Category). These are passed to this function by a read method in another class.
What I need to do is extract a generalized description of each category, which in all cases is the third instance of category specification (that is, always between the third and fourth ">" in every k-v pair).
My idea was to simply put all values in an arraylist, and for every value extract a string from between the third and fourth ">".
I recommend using the following map:
Map<Integer, List> map = new HashMap<>();
String[] vals = new String[] { "HomeRecipe", "Main Dish", "Chicken",
"Chicken Breasts" };
map.put(1, Arrays.asList(vals));
Then, if you need to find a given value in your original string using an ID, you can simply call ArrayList#get() at a certain position. If you don't care at all about order, then a map of integers to sets might make more sense here.
If you can. change your data structure to a HashMap<Integer, List<String>> or HashMap<Integer, String[]>. It's better to store the categories (by cats you mean categories right?) in a collection instead of a string.
Then you can easily get the third item.
If this is not possible. You need to do some debugging. Start by printing every input and output pair and find out which input caused the unexpected output. Your indexOf method seems to work at first glance.
Alternatively, try this regex method:
String k = cats.replaceAll("(?:[^>]+\\s*>\\s*){3}([^>]+).*", "$1");
System.out.println(k);
The regex basically looks for a xxx > yyy > zzz > aaa ... pattern and replaces that pattern with aaa (whatever that is in the original string).
For a school assignment, I have successfully created a program which stores recipes (name, ingredients, instructions). I now need to add a shopping list feature which will take the ingredients from the recipes I've added and store them in a new static string array.
I have been required to create the ingredients string array with a size of 20 and the shoppingList as a static string array with a size of 40:
private String[] ingredients = new String[20];
private static String[] shoppingList = new String[40];
I initialized all elements of both arrays to an empty string.
I've also hard coded two recipes in my test program like this:
rcp1.setIngredients(0, "Butter");
rcp1.setIngredients(1, "Garlic");
rcp1.setIngredients(2, "Parsley");
rcp1.setIngredients(3, "Bread");
rcp1.setIngredients(4, "Cheese");
rcp2.setIngredients(0, "Biscuits");
rcp2.setIngredients(1, "Pepperoni");
rcp2.setIngredients(2, "Pizza sauce");
This is where I get stumped:
public void setIngredients(int loc, String ingredient) {
ingredients[loc] = ingredient;
for (int i=0; i<shoppingList.length; i++){
if (shoppingList[loc] == "") {
shoppingList = ingredients;
}
}
}
Because the ingredients of rcp1 and rcp2 both use the ingredients locations [0, 1, 2], trying to add the ingredient to the static shoppingList using [loc] results in it overwriting those locations of the first recipe.
I've created the for loop so it could properly display the first recipe's ingredients; however, I'm not sure how to then proceed to find the location of the next empty string in order to list the ingredients of the second recipe. I was thinking that I would have to use an else if statement and then figure out a way to find where the next empty string is so I can begin to add the next recipe's ingredients from that point..?
Is there any other, possibly simpler, way that I could take the ingredients from rcp2 and place them after rcp1's ingredients in shoppingList?
I think I've been over-analyzing this problem and I haven't been able to find a solution yet, so I'd greatly appreciate it if anyone could point me in the right direction. Thank you!
You are running into a lot of artificial constraints, which is expected since this is a course assignment. Your main problem is that - apparently - you don't know how many ingredients are in each recipe, or in the shopping list. Normally, the array would be the right size for the contents so you would have the number of items in arr.length. Otherwise one would use one of the classes in the collections framework, like ArrayList.
However, you are using fixed-size buffers, which means that you need to track the current size of your list in addition to the capacity, which is what arr.length gives you. There are two ways you can do it:
Explicitly, by having an int variable that is conceptually associated with the array to mean "first unused element". When you add new elements, you would start at that index, and increment that variable for every new ingredient added to the list. This is what ArrayList does.
Implicitly, by having some kind of "marker" String that would mean "unused". This can be a proper String instance, or simply null. This is basically what C does with the '\0' string terminator.
Each option has different trade-offs and requires a different implementation, which I'm not adding here since you need do think about it as part of your course! Do not hesitate to ask more if you're stuck again, though.
I am extremely unsure of how to do this. I understand (I believe) that you use
String[] user {"stuff","other stuff","more stuff"};
I'm developing a chat bot and I need it to be able to recognize what the user said and if it's inside of the array (it's "database," per say), then it will respond accordingly.
Something simple so that I could be able to say, "How are you?" And it would look for "How are you?" or something at least close to it and respond accordingly with a random positive word. I've achieved this function by simply using lots of if-else statements, but this is far too much coding.
If I understand you correctly, you want your bot to respond to some prompt from the user. In that case, you could use a Map<String, String> to store query-answer pairs.
Map<String, String> answers = new HashMap<String, String>();
answers.put("How are you?", "Great!");
answers.put("Where is the cake?", "The cake is a lie");
and then just check whether the query string is in answers:
public String answerUser(String query) {
if (answers.containsKey(query)) {
return answers.get(query);
} else {
return "I don't understand.";
}
}
If you want more than one possible answer, use a Map<String, List<String>> and select randomly from the list:
public String answerUser(String query) {
Random rand = new Random();
if (answers.containsKey(query)) {
List<String> ans = answers.get(query);
int id = rand.nextInt(ans.size());
return ans.get(id);
} else {
return "I don't understand.";
}
}
This is a very big and complicated subject, and you haven't really posted enough to go on.
To split a string into words use String#split(), that will give you the array you want. (you probably want to split on all non-alpha, or all whitespace).
You then want to define keywords that your AI responds to, and scan the array for any of those keywords.
Use some sort of scoring system to then determine the appropriate response.
For example you could have a HashMap of String to a class that has both a weight and a meaning. Go through the sentence, sum up the scores for every action you find. Take appropriate decisions based on the combined values.
That's a very simple algorithm and much better ones are possible but they are a lot harder and this will get you started.
You could use a list instead of array, which will give you the contains() method. For instance:
List<String> words = new ArrayList<String>();
words.add("Hello");
words.add("bye");
if(words.contains("hello")) {
//do something
}
Another option would be to map the phrase to the response:
Map<String, String> wordMap = new HashMap<String, String>();
wordMap.put("How are you?", "Great");
wordMap.put("Where are you?", "Work");
wordMap.get("How are you?");
Combine these and map a phrase to a list of responses if you want.
An intelligent chat bot would need a lot more design, but if you just wanted a solution where "I say this, then you say that" than you could do it a couple ways.
Using Two Arrays
Since you know how to use one array, Figured I'd start here for simplicity.
String[] userInput {"how are you", "how are you?", "how you doing?"};
String[] response {"good", "terrible", "is that a joke?"};
//Go through each userInput string and see if it matches what you typed in.
//If it matches, print the corresponding position in the response array.
Using a Map
Same idea, but is a collection that is more suited for the situation.
Map<String, String> response = new HashMap<String, String>();
response.add("how are you", "good");
//When you receive input, check the response map using the input as the key.
//Return the value as the response.
//Better documented in sebii's answer.
I have a csv file with unknown amount of columns and row. The only thing I know is that each entry is separated by a comma. Can I use the split method to convert each line of the data into an array and then can I store that Array into an Arraylist. One of the things that concerns me is would I be able to rearrange the Arraylist alphabetically or numerically.
I would suggest using OpenCSV. If you just split on the comma separator, and you happen to have a single cell text containing a comma, but which is enclosed in double quotes to make it clear that it's a single cell, the split method won't work:
1, "I'm a single cell, with a comma", 2
3, hello, 4
OpenCSV will let you read each line as an array of Strings, handling this problem for you, and you can of course store each array inside a List. You will need a custom comparator to sort your list of lines. Search StackOverflow: the question of how to sort a list comes back twice a day here.
Yes, you can use:
String[] array = input.split("\",\"");
List<String> words = new ArrayList<String>(Arrays.asList(array))
Note that Arrays.asList(..) also returns a List, but you can't modify it.
Also note that the above split is on ",", because CVSs usually look like this:
"foo","foo, bar"
Using split with simple comma is not a fool proof one. If your column data contains a comma, csv would be stored something like a,"b,x",c. In such case split would fail.
I'm not a regex expert maybe someone could write a EMBEDDED_COMMA_DETECTING_REGEX or GIYF.
String[] array = input.split(EMBEDDED_COMMA_DETECTING_REGEX);
List<String> words = new ArrayList<String>(Arrays.asList(array));
There are several questions here so I'll cover each point individually.
Can I use the split method convert each line of the data into an array
This would work as you expect in the naive case. However, it doesn't know anything about escaping; so if a comma is embedded within a field (and properly escaped, usually by double-quoting the whole field) the simple split won't do the job here and will chop the field in two.
If you know you'll never have to deal with embedded commas, then calling line.split(",") is acceptable. The real solution however is to write a slightly more involved parse method which keeps track of quotes, and possibly backslash escapes etc.
...into an array than can I store that Array into an Arraylist
You certainly could have an ArrayList<String[]>, but that doesn't strike me as particularly useful. A better approach would be to write a simple class for whatever it is the CSV lines are representing, and then create instances of that class when you're parsing each line. Something like this perhaps:
public class Order {
private final int orderId;
private final String productName;
private final int quantity;
private final BigDecimal price;
// Plus constructor, getters etc.
}
private Order parseCsvLine(String line) {
String[] fields = line.split(",");
// TODO validation of input/error checking
final int orderId = Integer.parseInt(fields[0]);
final String productName = fields[1];
final int quantity = Integer.parseInt(fields[2]);
final BigDecimal price = new BigDecimal(fields[3]);
return new Order(orderId, productName, quantity, price);
}
Then you'd have a list of Orders, which more accurately represents what you have in the file (and in memory) than a list of string-arrays.
One of the things that concerns me is would I be able to rearrange the Arraylist according alphabetically or numerically?
Sure - the standard collections support a sort method, into which you can pass an instance of Comparator. This takes two instances of the object in the list, and decides which one comes before the other.
So following on from the above example, if you have a List<Order> you can pass in whatever comparator you want to sort it, for example:
final Comparator<Order> quantityAsc = new Comparator<Order>() {
public int compare(Order o1, Order o2) {
return o2.quantity - o1.quantity; // smaller order comes before bigger one
}
}
final Comparator<Order> productDesc = new Comparator<Order>() {
public int compare(Order o1, Order o2) {
if (o2.productName == null) {
return o1.productName == null ? 0 : -1;
}
return o2.productName.compareTo(o1.productName);
}
}
final List<Order> orders = ...; // populated by parsing the CSV
final List<Order> ordersByQuantity = Collections.sort(orders, quantityAsc);
final List<Order> ordersByProductZToA = Collections.sort(orders, productDesc);