Click just ones - java

I have a JTextPane to display questions call Qus, I have 4 JLabel, A, B, C, D. And five questions on different pages. When you select the correct answer a,b,c,or d, 10 point is added to a JLabelcall Counter.
But my problem is, it time u click a,b,c,d it keeps adding 10 again, again, and again. I just want it to add 10 once on each page, if answer is correct on next page, it should add another 10 not multiple 10 on a page or answer, that will be a cheat.
Here is the code
// To display the result
string preval = Counter.get text()+" ";
Counter.setText("0");
//Pls note Counter is to display result in the GUI
//Now the question method
Public void init() {
Call question==0;
}
//First Question
If(callquestion==1) {
Qus.setText(" 1+1");
A.setText("A) 2");
B.setText("A) 8");
C.setText("A) 9");
D.setText("A) 10");
}
//Answer, let's assume the answer is A// note A, B, C, D are all JLables
Private void AmouseClicked(java.awt.event.MouseEvent evt) {
If(callquestion==1 && D.isFocusable()) {
Int d= Integer.parseInt(Counter.getText());
Int e= 10;
Int f=d+10;
Counter.setText(f+" ");
}
}
Please note this is just 1 question and answer. In my project I have 20 of this. I just want each button to add 10 once, and adding it on multiple clicks Thanks

Since you're going for one question at a time, why not reuse the page?
:)
First, we create a Question class...
class Question{
String question;
String answer1, answer2, answer3, answer4;
int userAnswer;
int correctAnswer;
boolean scoredPoints;
Question(String q, int correct, String a1, String a2, String a3, String a4){
this.question = q;
this.correctAnswer = correct;
this.answer1 = a1;
this.answer2 = a2;
this.answer3 = a3;
this.answer4 = a4;
}
}
Then we can create the question...
Question q1 = new Question("1+1",1,"2","4","6","8");
//constructor is question, correct answer, ans 1, 2, 3, 4.
Then create a list of Questions...
ArrayList<Question> questions = new ArrayList<>();
And add the Questions to the list...
questions.add(q1);
Then you do the same things you'd do to present the question, however, you'd reference questions.get(x) where x is the question number (minus one, since array index 0 is equal to object 1).
When a user presses a button, such as A, you call your actionlistener and invoke:
questions.get(x).scoredPoints = true; //prevents cheating
questions.get(x).userAnswer = buttonNumber; //sets user question answer
x in this case is the current question number.
This way you can have a continuous stream of questions, their answers will be recorded and checked, and they cannot "cheat".

I guess what the problem is: The AmouseClicked method gets called whenever a mouseevent occures (mouse_pressed, mouse_down, mouse_release). So this should do the trick.
If(callquestion==1 && D.isFocusable())
needs to be
If(callquestion==1 && D.isFocusable() && evt.getModifiersEx()==MouseEvent.MOUSE_PRESSED)

Instead of storing the points directly use a map (question, answer) to store in which question what answer the user gave:
// somewhere in your main programme
List<Integer> userAnswers;
List<Integer> correctAnswers;
...
// at programme startup initialise to #answers
userAnswers = Arrays.toList(new Integer[20]); // create list full of null
correctAnswers = new ArrayList<Integer>();
for(int i = 0; i < 20; ++i)
correctAnswers.add(0); // set all correct answers to #a (change this accordingly)
...
// when user answers question #q with answer #a
userAnswers.set(q, a); // set answer at #q to #a
Counter.setText(getScore() + " "); // update the counter every time the list changes!
...
// getScore counts up the awarded points for all questions
private int getScore() {
int sum = 0;
for(int q = 0; q < correctAnswers.size(); ++q) {
int expected = correctAnswers.get(q); // assume initialised
Integer actual = userAnswers.get(q); // may be null
if(actual != null && actual == expected)
sum += 10; // or have a third list indicating how many points each question awards
}
}
This has other advantages like you being able to tell the user in the end exactly which answers he got right and which ones he got wrong.

If I understand you correctly, I believe this is a better solution for your problem:
What you do in your setup:
JLabel a = new JLabel()
a.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
aclicked();
}
});
JLabel b = new JLabel()
b.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
bclicked();
}
});
//do this for c and d as well
The methods aclicked and bclicked is where you check if the right answer is given, and if so, award the points.

Related

Cannot invoke because Array[] is null [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed last year.
I'm still new to programming and I want to make a program that will take the food order from user until the user presses "n" to stop. But I can't seem to make it work like I want it to.
I want my output to be like this.
Buy food: Burger
Order again(Y/N)? y
Buy Food: Pizza
Order again(Y/N)? n
You ordered:
Burger
Pizza
But my output right now is this.
Buy food: Burger
Order again(Y/N)? y
Buy food: Pizza
Order again(Y/N)? n
You ordered:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Array.getFoodName()" because "food_arr2[i]" is null
at Food.main(Food.java:50)
Here is my code:
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Food food = new Food();
Array[] food_arr;
boolean stop = false;
String foodName;
int k = 1;
int j = 0;
while(stop == false) {
food_arr = new Array[k];
System.out.print("Buy food: ");
foodName = s.next();
food_arr[j] = new Array(foodName);
food.setFoodArray(food_arr);
System.out.print("Order again(Y/N)? ");
String decide = s.next();
if(decide.equalsIgnoreCase("y")) {
k++;
j++;
}
else if(decide.equalsIgnoreCase("n")) {
stop = true;
}
}
Array[] food_arr2 = food.getFoodArray();
for (int i = 0; i < food_arr2.length; ++i) {
System.out.println("\nYou ordered: ");
System.out.println(food_arr2[i].getFoodName()); //This line is the error according to my output
}
}
I don't know how to fix this and I was hoping for someone to help me.
I think I see what you are trying to do with the k value setting the size of the array you are using.
However, with each iteration of the while loop:
food_arr = new Array[k];
Will create a new empty array each time!
So, for example, on the second iteration
food.setFoodArray(food_arr);
Will set foods array as something like [null, "Pizza"]
Even if this did work, creating a new array each time is not a very efficient method.
I would strongly recommend using a different, dynamically allocated data structure such as an ArrayList and defining it outside the scope of the while loop.
ArrayList<Food> food_arr = new ArrayList<Food>()
// Note that I'm just guessing the data type here - I can't see what you are actually using!
while(stop == false) {
System.out.print("Buy food: ");
foodName = s.next();
food_arr.add(foodName)
// etc, etc
}
food.setFoodArray(food_arr)
// ! Note: You will need to convert the array list into an array
// ! or change the data struture in the Food class
// etc, etc
However, this is just the first solution that popped into my head, check out different kinds of data structures and think about how else you could design this program yourself!

I have made a Java programme but has repetition problem

I have created that Java programme but it have repetition problem, I want that if one question has done either right or wrong it must not be ask again.
It should ask 10 question only. I have tried alot to change but every time I am getting error.
I have created that Java programme but it have repetition problem, I want that if one question has done either right or wrong it must not be ask again.
It should ask 10 question only. I have tried alot to change but every time I am getting error.
package examapp;
import java.util.Random;
import javax.swing.JOptionPane;
public class Examapp {
static int nQuestions = 0; static int nCorrect = 0;
public static void main(String[] args) {
int prevNum=0;
int sum=0;
do{
Random rand = new Random();
int randomNum = rand.nextInt((11 - 1) + 1) + 1;
if(randomNum==prevNum){
prevNum=randomNum;
}
else if(randomNum==1){
String question1;
question1 = "What was the name of Google in late 90s?\n";
question1+="A. Googol\n";
question1+="B. Gigablast\n";
question1+="C. Backrub\n";
question1+="D. Google\n";
question1+="Marks=9";
check(question1,"C");
sum=sum+1;
}
else if(randomNum==2){
String question2;
question2 = "\"Do no evil\" is a tagline of?\n";
question2+="A. Yahoo\n";
question2+="B. Google\n";
question2+="C. Bing\n";
question2+="D. Duck Duck Go\n";
question2+="Marks=9";
check(question2,"B");
sum=sum+1;
}
else if(randomNum==3){
String question3;
question3 = "Which of the following is fully Object Oriented Programming Language?\n";
question3+="A. SmallTalk\n";
question3+="B. Kotlin\n";
question3+="C. Java\n";
question3+="D. F#\n";
question3+="Marks=9";
check(question3,"A");
sum=sum+1;
}
else if(randomNum==4){
String question4;
question4 = "Which among the following is not a mobile Operating System?\n";
question4+="A. Bada\n";
question4+="B. Safari\n";
question4+="C. WebOS\n";
question4+="D. MeeGo\n";
question4+="Marks=9";
check(question4,"B");
sum=sum+1;
}
else if(randomNum==5){
String question5;
question5 = "Which of the following is a correct format of Email address?\n";
question5+="A. info.website.com\n";
question5+="B. info#website.com\n";
question5+="C. info#website#com\n";
question5+="D. info.website#com\n";
question5+="Marks=9";
check(question5,"B");
sum=sum+1;
}
else if(randomNum==6){
String question6;
question6 = "What is the shortcut key of printing a document for computer having windows?\n";
question6+="A. Ctrl + Shift + P\n";
question6+="B. Alt + P\n";
question6+="C. Ctrl + Alt + P\n";
question6+="D. Ctrl + P\n";
question6+="Marks=9";
check(question6,"D");
sum=sum+1;
}
else if(randomNum==7){
String question7;
question7 = "Computer software includes\n";
question7+="A. Packaged programs\n";
question7+="B. Operating system programs\n";
question7+="C. Applications programs\n";
question7+="D. All of these\n";
question7+="Marks=9";
check(question7,"D");
}
else if(randomNum==8){
String question8;
question8 = "A function inside another function is called a _______ function\n";
question8+="A. Nested\n";
question8+="B. Round\n";
question8+="C. Sum\n";
question8+="D. Grouped\n";
question8+="Marks=9";
check(question8,"A");
sum=sum+1;
}
else if(randomNum==9){
String question9;
question9 = "What does HTTP stands for?\n";
question9+="A. Hypertext Transfer Plotter\n";
question9+="B. Hypertext Transfer Plot\n";
question9+="C. Hypertext Transfer Protocol\n";
question9+="D. Head Tail Transfer Protocol\n";
question9+="Marks=9";
check(question9,"C");
sum=sum+1;
}
else if(randomNum==10){
String question10;
question10 = "The term 'Pentium' is realted to\n";
question10+="A. DVD\n";
question10+="B. Hard Disk\n";
question10+="C. Microprocessor\n";
question10+="D. Mouse\n";
question10+="Marks=9";
check(question10,"C");
sum=sum+1;
}
else{
prevNum=randomNum;
}
}while(sum<=9);
JOptionPane.showMessageDialog(null,nCorrect + " correct out of 10" + " questions");
JOptionPane.showMessageDialog(null,"Total Obtained Marks="+(nCorrect*9));
}
public static String ask(String question) {
while(true) {
String answer = JOptionPane.showInputDialog(question);
answer = answer.toUpperCase();
if(!(answer.equals("A") || answer.equals("B") || answer.equals("C") || answer.equals("D"))){
JOptionPane.showMessageDialog(null,"Invalid Answer");
continue;
}
return answer;
}
}
static void check(String question, String correctAnswer) {
nQuestions++;
String answer = ask(question);
if(answer.equals(correctAnswer)) {
nCorrect++;
}
else {
}
}
}
Thank you!
Your main is quite cluttered. By the time you get to the bottom, you have already forgotten what was on top, such as that it is a very large do-while block. If I were you, I would put the questions and answers in an array, list or even better in your own question object. Then you could use array shuffle to put them in different order for each run and omit all the if-else blocks. It is best to also pull your initialization from random out of the loop so that you don't create a new object with every iteration.
In order to answer your question, so that you do not use an already generated random number again, you must somehow remember the already generated ones. For example, use a list.
public static void main(String[] args) {
Random rand = new Random();
List<Integer> list = new ArrayList<>();
int count = 0;
int randomNum;
do{
randomNum = rand.nextInt(10)+1;
while(list.contains(randomNum)){
randomNum = rand.nextInt(10)+1;
}
list.add(randomNum);
count++;
// rest of your code goes here
}while( count < 10);
System.out.println(list);
}

Create a random quiz mode where every array part is only called once

I'm a bit new to Android Studio and I want to make small quiz app. On the start screen, there are two buttons. With the first button, you just click through your questions and you can start at a specific question number if you want (this is already working). With the second button, I wand to create a random mode BUT every question should only be asked once. So there should not be the possibility to get the same questions twice.
For that I created an Array:
public ArrayList<Integer> questionsDone = new ArrayList<>();
And got the lenght of the Question Array:
public int maxQuestions = QuestionLibrary.nQuestions.length;
then I have a function for updating the question:
private void updateQuestion(){
//RANDOM MODE
if (startNumber == -1) {
if (questionsDone.size() >= maxQuestions) {
finishQuiz();
} else {
nQuestionNumber = (int) (Math.random() * (maxQuestions));
do {
if (questionsDone.contains(nQuestionNumber)) {
nQuestionNumber = nQuestionNumber - 1;
if (nQuestionNumber == -1) {
nQuestionNumber = maxQuestions-1;
}
} else {
questionsDone.add(nQuestionNumber);
notDone = true;
}
} while (notDone = false);
}
}
nQuestionView.setText(nQuestionLibrary.getQuestion(nQuestionNumber));
nButtonChoice1.setText(nQuestionLibrary.getChoice1(nQuestionNumber));
nButtonChoice2.setText(nQuestionLibrary.getChoice2(nQuestionNumber));
nButtonChoice3.setText(nQuestionLibrary.getChoice3(nQuestionNumber));
So my idea was that when I start random mode, I pass the value "-1". If the size of the array (questions were done) equals the number of the available questions the quiz should stop. If not, I just get a random number and multiply it by the number of questions. Then there is a do-while function which makes sure that if the questionsDone-Array already contains the number it will get a new number and after getting a number which is not in the array it will be stored in the array.
This is what the app does when I click on random mode:
It always shows a random question but sometimes one questions are asked twice and more. And suddenly it stops (the app is loading the result page) but the stop does not come with a pattern. When I have 7 questions, each question is minimum asked once and sometimes it stops after 15, sometimes after 20 questions and so on.
Does someone know why?
Since I wanted to give an update to both of you, I posted an anwser. Thank you guys for the good input. It works now and this is how I got it working:
First I created an array:
public ArrayList<Integer> availableQuestions = new ArrayList<>();
Then i put integers in the array starting by 0 and ending maxQuestions-1 and I shuffled the values:
if (startNumber == -1) {
Integer i = 0;
do {
availableQuestions.add(i);
i++;
}while (i < maxQuestions);
Collections.shuffle(availableQuestions);
}
Then on every button click this function starts to work (j was declared as an integer with the value 0 before):
if (startNumber == -1) {
nQuestionNumber = availableQuestions.get(j);
j++;
}
Instead of keeping QuestionsDone, I suggest to keep QuestionAvailable (i.e. not yet answered), as indices of questions in the library
List<Integer> availableQuestions = null;
...................................................
if (startNumber == -1) {
if (availableQuestions.isEmpty()) {
finishQuiz();
availableQuestions = null;
} else {
if (availableQuestions == null) {
// Starting a new quiz
availableQuestions = new List<Integer>(maxQuestions);
for (int i=0; i<maxQuestons; i++) availableQuestions.Add(i);
}
int nQuestionOrder = (int) (Math.random() * availableQuestions.size());
nQuestionNumber = availableQuestions.get(nQuestionOrder);
availableQuestions.removeAt(nQuestionOrder);
}
}

Working with Generic arrays [duplicate]

This question already has answers here:
Java generics and Array's
(5 answers)
Closed 8 years ago.
Good day. I have been learning java the last few months. So I created a generic array as follows.
public class Implementation<T> implements IMatrix<T>{
private T[][] genMatrix;
private Integer numberRows;
private Integer NumberCols;
public Implementation(){
generateMatrix();
for(int i = 0;i< numberRows;i++)
{
for(int j =0;j< numberCols;j++)
{
JOptionPane.showInputDialog("Enter value for row " + (i+1) + " and for column " + (j+1)))
}
}
multiplyScalar(5);
}
//generate the array
public void generateMatrix(){
String rowString = JOptionPane.showInputDialog("Enter the number of rows!");
numberRows = Integer.parseInt(rowString);
String colString = JOptionPane.showInputDialog("Enter the number of cols!");
numberCols = Integer.parseInt(colString);
final Object[][] arrayO = (T[][])new Object[numberRows][numberCols];
genMatrix = (T[][])arrayO;
}
//writeElements to the array;
public void writeElem(int x, int y, T value){
genMatrix[x][y] = value;
}
//now that those members are done I have created a method to access the data
public T getElem(Integer i, Integer j){
return (T)genMatrix[i][j];
}
This is where my problem now exists. I have made this two dimensional array. I would like to multiply each value in this array by a Integer c. I have attempted it in the following way and all failed.
public IMatrix<T> multiplyScalar(Integer c) throws MatrixException {
// TODO Auto-generated method stub
for(int i = 0; i< numberRows; i++)
{
for(int j=0;j<numberCols;j++)
{
/**
THIS IS THE POINT AT WHICH IT CRASHES
*/
System.out.println(((Integer)(getElement(i, j)) * c));
}
}
return null;
}
}
The program crashes because of a ClassCastException. I have tried everything in my knowledge to get this to work. I can not multiply the two dimensional array with a Integer. Please help. This uses a interface with many more functions that is irrelevant. Please note that there is a strong possibility that this code crashes as I can not upload the original code.
The problem is that Java doesn't support operator polymorphism. You need T to extend Number and then use method calls. Its a bit more verbose than what one might like though. Its explained quiet well here:
Predefining multiplication for generics in java

Java Sorting a 2D String Array not working anymore

Ok so i am working on a way to sort a 2D array, one of the dimensions having a string then the other having an int (Stored as a string for convenience sake) I had looked everywhere for a solution on how to sort the arrays in a way that the data from firstArray[1] is moved at the same time (its index's are a child to the movement of:) as firstArray[0]
This effect was achieved by using this
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
Now i am having troubles with the thing. I will step through the code here and please if you can find a problem with it do tell.
First off i have the array:
String[][] fps = new String[2][15];
Arrays.fill(fps[0], "empty");
Arrays.fill(fps[1], "0");
Second i fill the array with some things that the other part of the program gives me, for this example ill use garbage values:
fps[0][0] = "Java";
fps[1][0] = "1";
fps[0][1] = "C++";
fps[1][1] = "14";
fps[0][2] = "C#";
fps[1][2] = "21";
fps[0][3] = "Python";
fps[1][3] = "9001";
Now is where i would call the above sorting command (Note that these values do not completly fill the array, there are some bins where there is no new data.)
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
Now we have the array sorted and i want to search the 2D array for a value, so i use the Arrays.search to find which bin the query is at.
int searchIndex = Arrays.binarySearch(fps[0], "Java");
System.out.println(searchIndex);
So that is the code, and i think i have isolated the problem to being that the sorting part is not working correctly. If any of you have any more questions please post them in the comments. Likewise if you have a possible solution to this puzzling problem, I would love to hear of it!
PS: Just to be clear I had this working, then i shutdown my lappy and next time i booted (and since then) it has not worked.
PPS: As requested the outputs:
Current output:
-16
FPS:
0 ---- No FPS For you!
1 ---- Only one FPS
2 ---- Only two FPS
3 ---- Only three FPS
4 ---- Only four FPS
5 ---- Only five FPS
6 ---- Only six FPS
7 ---- Only seven FPS
8 ---- Only eight FPS
9 ---- Only nine FPS
1 ---- Blah!
Expected/Hoped Output:
-16
FPS:
1 ---- Blah!
0 ---- No FPS For you!
8 ---- Only eight FPS
5 ---- Only five FPS
4 ---- Only four FPS
9 ---- Only nine FPS
1 ---- Only one FPS
7 ---- Only seven FPS
6 ---- Only six FPS
3 ---- Only three FPS
2 ---- Only two FPS
PPPS: If you would like to see the code that i am working with currently:
import java.util.*;
public class Test
{
public static void main (String [] args)
{
String[][] fps = new String[2][15];
Arrays.fill(fps[0], "empty");//Fill up all the spaces so the sort and the search dont crap out
Arrays.fill(fps[1], "0");
//fps[ROW][COLOUMN] = Value + "";
//fps[ROW][COLOUMN] = Value Instances + "";
fps[0][0] = "No FPS For you!";
fps[1][0] = 0 + "";
fps[0][1] = "Only one FPS";
fps[1][1] = 1 + "";
fps[0][2] = "Only two FPS";
fps[1][2] = 2 + "";
fps[0][3] = "Only three FPS";
fps[1][3] = 3 + "";
fps[0][4] = "Only four FPS";
fps[1][4] = 4 + "";
fps[0][5] = "Only five FPS";
fps[1][5] = 5 + "";
fps[0][6] = "Only six FPS";
fps[1][6] = 6 + "";
fps[0][7] = "Only seven FPS";
fps[1][7] = 7 + "";
fps[0][8] = "Only eight FPS";
fps[1][8] = 8 + "";
fps[0][9] = "Only nine FPS";
fps[1][9] = 9 + "";
/* FUMBLE WITH ARRAY AFTER THIS LINE ONLY!*/
//Things to have inputed into the method:
//currentValue (from the line)
//currentVariable (so we know what the name of the array we're dealing with is named)
String currentValue = "Blah!"; //This is the value that will be searched for in the array, if found its child int is incremented by one, if not found it is added to the array.
//Do a binary sort then search in the fps[0] side of things, makesure that the [1] are carried with the [0] changes.
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});
int searchIndex = Arrays.binarySearch(fps[0], currentValue); //Get the index of the current search value
System.out.println(searchIndex); // <-- Returns a neg number each time which shows that the sorting is not working correctly, and therefore the search is being thrown off... need to somehow fix.
if(searchIndex >= 0)// If the value is found
{
fps[0][searchIndex] = (Integer.parseInt(fps[0][searchIndex]) + 1) + ""; //Add one instance to the value
} //end if
else //Otherwise find the next open value spot and change it to the current search query (and assign its instances to 1
{
for(int i = 0; i < fps[1].length ; i++)
{
if(fps[1][i].equals("empty"))
{
fps[1][i] = currentValue;
fps[0][i] = 1 + "";
i = fps[1].length; //force the for loop to exit
Arrays.sort(fps, new Comparator<String[]>() {
#Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
}); //end Arrays.sort
}//end if
}//end for
}//end else
//... Print array in rectangular form
System.out.println("FPS:");
for (int i =0; (!(fps[1][i].equals("empty")) ) ; i++)
{
System.out.println("\t" + fps[0][i] + " ---- " + fps[1][i] );
}//end for
}//end main
}//end class
I believe you have your indexes backwards. You are sorting fps. fps has only 2 elements which are being sorted. I believe you are trying to sort the 15 elements. If you reverse your indexes I believe you will get the desired sorting.
String[][] fps = new String[15][2];
You might consider an array of objects rather than a 2d array in this case. It seems to be a more logical structure and would avoid this type of confusion.
In addition to the problem pointed out in this Answer, there is a problem in this:
int searchIndex = Arrays.binarySearch(fps[0], "Java");
Since you sorted using a custom comparator, you need to use the same custom comparator to do the binary search. Use binarySearch(T[] a, T key, Comparator<? super T> c). (If you use the 2-arg version, you should get an exception because String[] doesn't implement Comparable.)
do you have any resources about the objects (when used in a similar instance to this
See: Sorting using Comparator- Descending order (User defined classes) for an example of how to do this when using a custom object.
one of the dimensions having a string then the other having an int (Stored as a string for convenience sake)
Its not convenient, since sorting a String representation of a number is different than sorting a number. Using a custom object will allow you to store the data properly so you can have a proper sort.

Categories

Resources