性格测试数据统计(JAVA实现)
新开了一门外教课程,Object-oriented Programming(JAVA), 记录一些学习经验,以及部分和c++的区别感悟。本文为性格测试数据统计作业demo, 大概要求是对一个.txt文件里的数据进行统计并打印输出要求格式。
text输入文件格式如下:
…
Zhang San
BABAAAABAAAAAAABAAAABBAAAAAABAAAABABAABAAABABABAABAAAAAABAAAAAABAAAAAA
…
text输出文件格式如下:
…
Zhang San: [90, 15, 10, 10] = ISTJ
…
注:数字为选项B的比例,后边的字母为对应的性格,详见:Keirsy Temperament Sorter
相比上一篇文章(降雨绘图(JAVA实现)),本次作业的主要学习总结如下:
- class constant可以强增代码的可读性,对于编写文档有帮助,但有时也会使程序不那么灵活
- 数组array(包括int[] String[]等)是用引用方式references传递的
- 一条一条读进数据,再一条一条写到文件中,个人觉得更加合理。(因为当数据量较大时,内存可能无法一次读进来所有数据,有点像深度学习里训练网络需要用个生成器,边训练边送数据)
自己的总结与思考,目前水平有限,若有建议欢迎指教! 代码如下:
package demo;
import java.util.*;
import java.io.*;
public class Personality {
/*
* Some magic number of this program
* */
// most of arrays' capacity.
private static final int FOUR = 4;
// question group of personality.
private static final int QUEGROUP = 10;
// question number of one group.
private static final int QUENUM = 7;
// dimension index for combine i loop.
private static final int[] DIM = {0, 1, 1, 2, 2, 3, 3};
/*
* Four dimension of personality test
* X mean 50% result
* */
private static final String[] DIM0 = {"E", "I"};
private static final String[] DIM1 = {"S", "N"};
private static final String[] DIM2 = {"T", "F"};
private static final String[] DIM3 = {"J", "P"};
private static final String[][] PERDIM= {DIM0, DIM1, DIM2, DIM3};
private static final String X = "X";
// relative path
private static final String PATH = "./";
public static void main(String[] args) throws FileNotFoundException {
Scanner console_input = new Scanner(System.in);
openMenu();
Scanner input_file = readInString(console_input);
stasticDbFile(input_file, console_input);
closeMenu();
}
/*
* short introduction
* */
private static void openMenu()
{
System.out.println("You can obtain statistics data of the personality test in this program");
}
/*
* Ask the user for the name of the input.
* If not exist, ask again.
* */
private static Scanner readInString(Scanner console_input)
{
while (true)
{
System.out.print("personality test database file name? ");
String file_name = console_input.nextLine().trim();
String path = PATH + file_name;
try {
Scanner input_file = new Scanner(new File(path));
return input_file;
}
catch ( Exception e ) {
System.out.println("Please check the file name!");
}
}
}
/*
* Read the input file.
* Name the output file.
* */
private static void stasticDbFile(Scanner input_file, Scanner console_input) throws FileNotFoundException
{
String ouput_file = readOutString(console_input);
PrintStream output = new PrintStream(new File(ouput_file));;
while ( input_file.hasNextLine() )
{
String name = input_file.nextLine();
String data = input_file.nextLine();
statistics(name, data, output);
}
input_file.close();
}
/*
* Ask the user for the name of the output.
* */
private static String readOutString(Scanner console_input)
{
System.out.print("statistics data file name(ouput)? ");
String file_name = console_input.nextLine().trim();
return file_name;
}
/*
* statistics the input file.
* three main parts(methods) all in this part.
* compareAB: estimate A or B or X.
* percentB: B percent of every dimension.
* perType: dimension chose.
* */
private static void statistics(String name, String data, PrintStream output)
{
// counts of A and B
int A_count[] = new int[FOUR];
int B_count[] = new int[FOUR];
for (int i = 0; i < QUEGROUP; i++)
{
// every group have the same structure of questions.
int group = i * QUENUM;
for (int num = 0; num < QUENUM; num++)
{
// DIM use here to combine the i and question dimension.
// For example, i = 1 and 2, are the DIM1("S" or "N") question
compareAB(A_count, B_count, data.charAt(num+group), DIM[num]);
}
}
int[] B_percent = percentB(A_count, B_count);
String pertype = perType(B_percent);
// print the data of One person in the output file.
printAnswer(name, B_percent, pertype, output);
}
private static void compareAB(int[] A_count, int[] B_count, char data, int dim)
{
if (data == 'A' || data == 'a')
{
A_count[dim]++;
}
if (data == 'B' || data == 'b')
{
B_count[dim]++;
}
}
private static int[] percentB(int[] A_count, int[] B_count)
{
int[] B_percent = new int[FOUR];
for (int i = 0; i < FOUR; i++)
{
// turn in the double, than back to int.
B_percent[i] = (int) Math.round( ( ((double)B_count[i]) / ((double)(A_count[i]+B_count[i])) ) * 100 );
}
return B_percent;
}
private static String perType(int[] B_percent)
{
String pertype = " ";
for (int i = 0; i < FOUR; i++)
{
if (B_percent[i] > 50) { pertype = pertype + PERDIM[i][1]; }
else if (B_percent[i] < 50) { pertype = pertype + PERDIM[i][0]; }
else { pertype = pertype + X; }
}
return pertype;
}
/*
* print the data of One person in the output file.
* */
private static void printAnswer(String name, int[] B_percent, String pertype, PrintStream output)
{
output.println(name + ": [" + B_percent[0]+", "+ B_percent[1]+", "+B_percent[2]+", "+B_percent[3] + "] =" + pertype);
}
/*
* Say goodbye to user.
* a flag of program is finished
* */
private static void closeMenu()
{
System.out.println("statistics finshed! Bye!");
}
}