<更新日期03-31-2016> 复利计算5.0 <已改进>
作业要求:
1.客户说:帮我开发一个复利计算软件。
完成复利公式计算程序,并成功PUSH到github上。
客户提出:
2.如果按照单利计算,本息又是多少呢?
3.假如30年之后要筹措到300万元的养老金,平均的年回报率是3%,那么,现在必须投入的本金是多少呢?
完成23功能,并成功PUSH到github上。
客户又想:
4.利率这么低,复利计算收益都这么厉害了,如果拿100万元去买年报酬率10%的股票,若一切顺利,过多长时间,100万元就变成200万元呢?
5.如果我希望在十年内将100万元变成200万元,应该找到报酬率在多少的投资工具来帮助我达成目标?如果想在5年后本金翻倍,报酬率就应至少为多少才行呢?
6.如果每年都将积蓄的3万元进行投资,每年都能获得3%的回报,然后将这些本利之和连同年金再投入新一轮的投资,那么,30年后资产总值将变为多少?如果换成每月定投3000呢?
客户又想:
7. 你写的程序能让客户随意操作吗?误输入数据、不小心做了非常规的操作程序是什么反应?
8. 如果向银行贷款10万元,年利率6.5%,期限为10年,那么每月等额本息还款多少?(算复利条件下等额还款金额)
客户又想:
4.0............
12. 即要追求利益,又要面对不可预知的金融投资风险, “不能把鸡蛋放在同一个篮子里”,所以有必要进行组合投资。
通过上述计算与对比,可以帮助客户进行投资决策。
客户:那么能否帮我记录下一笔一笔不同类型的投资,并动态显示资金现值呢?
提问:动态显示资金现值是以什么形式进行呈现?
客户特么又想:
5.0 单元测试-----------------------------
仅对复利模块进行了测试,其他模块以此类推。
以下为测试新增代码:
public static double CompoundingCalculation(double money,double rate,int years) { int year = years; double Money = money,Rate = rate; double sum1 = 0; for (int i = 1; i <= year ; i++) { sum1 = Money*Math.pow(1.0 + Rate, year); } return sum1; }
Ps:为了测试数据,由于此前写的方法是不含参数的方法所以在进行测试的时候要构造一个带参数的同名方法进行传参测试。
测试模块 |
测试输入 |
预期结果 |
运行结果 |
bug跟踪 |
复利计算终值 |
(本金,年限,利率) |
终值 |
||
1 |
(10000,10,3) |
13439.16793441223 |
√ |
|
2 |
(-1,10,3) |
弹出提示:请输入正确的本金 |
旧版本没有提示 |
由于没用做窗口所以无法弹出窗口告诉用户出错,但是本程序纠错是用正则表达式,回调了所应用的计算函数。 |
3 |
(100,-1,3) |
弹出提示:请输入正确的的年限 |
旧版本没有提示 |
由于没用做窗口所以无法弹出窗口告诉用户出错,但是本程序纠错是用正则表达式,回调了所应用的计算函数。 |
单利计算终值 |
(本金,年限,利率,次数) | 终值 | ||
1 |
(10000,10,3)
|
19000.0 | √ | |
2 | (-1,10,3 ) | 弹出提示:请输入正确的本金 | 旧版本没有提示 | 由于没用做窗口所以无法弹出窗口告诉用户出错,但是本程序纠错是用正则表达式,回调了所应用的计算函数。 |
3 | (100,-1,3) | 弹出提示:请输入正确的的年限 | 旧版本没有提示 | 由于没用做窗口所以无法弹出窗口告诉用户出错,但是本程序纠错是用正则表达式,回调了所应用的计算函数。 |
单元测试小结:
1、个人理解的单元测试就是可以找出程序在数据和逻辑上在编译时无法找出的的一些错误,并查具体位置。
2、本程序使用了正则表达式< "^\\d+(\\.\\d+)?$" >在一定程度上可以大大降低在单元测试前数据出错的问题。
3、本程序在输入数据上没有对“0”值进行控制。因为数据输入的方式是以字符串的方式进行输入然后再通过数据转换转成整型或者双精度型。
正则表达式的函数的pattern() 返回正则表达式的字符串形式,需要返回Pattern.complile(String regex)的regex参数
Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false,matches()对整个字符串进行匹配,只有整个字符串都匹配了才返回true
参考帖子:http://www.cnblogs.com/ggjucheng/p/3423731.html
public static boolean isNumeric(String str) { Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)?$"); Matcher isNum = pattern.matcher(str); if( !isNum.matches() ){ return false; } return true; }
代码小结:
1、代码在实现上还有很多地方可以修改,有的地方的代码不断复用,定义的数据类型没有实现封装,等等。
希望助教,老师可以给点在代码优化上的意见~
完成情况:
代码已提交至github
地址:https://github.com/sunhailin-Leo/Compounding-test-1<已更新5.0>
此前代码仅为一个.java文件,此次提交将整个工作文件提交至github
BUG:容错功能还没完善<0320 1800前>.
容错功能已完善但不完美,如果在调试窗口使用组合键会报错。<0320 2100>
正则表达式实现数据的错误检测。<0331 2030>
1 package Calulation; 2 3 import java.util.Scanner; 4 import java.util.regex.Matcher; 5 import java.util.regex.Pattern; 6 7 8 public class Calculate { 9 static Scanner scanner = new Scanner(System.in); 10 //正则判断是否为数字选项 11 public static boolean isNumeric(String str) 12 { 13 Pattern pattern = Pattern.compile("^\\d+(\\.\\d+)?$"); 14 Matcher isNum = pattern.matcher(str); 15 if( !isNum.matches() ){ 16 return false; 17 } 18 return true; 19 } 20 21 //字符型转整型 22 public static int StringToInt(String intstr) 23 { 24 Integer integer; 25 integer = Integer.valueOf(intstr); 26 return integer.intValue(); 27 } 28 29 //字符型转double型(该功能尚未使用) 30 public static double StringToDouble(String str) 31 { 32 Double data; 33 data = Double.valueOf(str); 34 return data.doubleValue(); 35 } 36 37 //double型转字符型(该功能尚未使用) 38 public static String DoubleToString(double value) 39 { 40 double dd = value; 41 String str = String.valueOf(dd); 42 return str; 43 } 44 45 public static void main(String[] args) 46 { 47 System.out.println("请选择单利计算或复利计算:(复利选1,单利选2,本金计算选3,投资预期年份计算选4,投资预期利率计算选5,定额复利投资递增性选6,贷款月还款金额计算选7)"); 48 String choice = scanner.next(); 49 if(isNumeric(choice)) 50 { 51 switch(StringToInt(choice)) 52 { 53 case 1: 54 CompoundingCalculation(); 55 break; 56 case 2: 57 SimpleInterestCalculation(); 58 break; 59 case 3: 60 PrincipalCalculation(); 61 break; 62 case 4: 63 CalculateRewardTime(); 64 break; 65 case 5: 66 CalculateInterest(); 67 break; 68 case 6: 69 IncreasingInterestInvestmentQuota(); 70 break; 71 case 7: 72 MatchingInterestRepaymentCalculator(); 73 break; 74 } 75 } 76 else 77 { 78 System.out.println("输入错误!,请重新输入!"); 79 main(null); 80 } 81 } 82 83 public static void CompoundingCalculation() 84 { 85 String money,rate,years; 86 int Year=0; 87 double Rate=0,Money=0,sum1=0; 88 System.out.println("请输入本金:"); 89 money = scanner.next(); 90 if(isNumeric(money)) 91 { 92 Money = StringToDouble(money); 93 } 94 else 95 { 96 System.out.println("输入错误!,请重新输入!"); 97 CompoundingCalculation(); 98 } 99 System.out.println("请输入存款年数:"); 100 years = scanner.next(); 101 if(isNumeric(years)) 102 { 103 Year = StringToInt(years); 104 } 105 else 106 { 107 System.out.println("输入错误!,请重新输入!"); 108 CompoundingCalculation(); 109 } 110 System.out.println("请输入年利率:"); 111 rate = scanner.next(); 112 if(isNumeric(rate)) 113 { 114 Rate = StringToDouble(rate); 115 } 116 else 117 { 118 System.out.println("输入错误!,请重新输入!"); 119 CompoundingCalculation(); 120 } 121 for (int i = 1; i <= Year; i++) 122 { 123 sum1 = Money*Math.pow(1.0 + Rate, Year); 124 } 125 System.out.println("存入第" + Year + "年后的存款总额为:" + sum1); 126 main(null); 127 } 128 129 public static void SimpleInterestCalculation() 130 { 131 String money,rate,years; 132 double Money=0,sum1=0,Rate=0,interest=0; 133 int Year=0; 134 System.out.println("请输入本金:"); 135 money = scanner.next(); 136 if(isNumeric(money)) 137 { 138 Money = StringToDouble(money); 139 } 140 else 141 { 142 System.out.println("输入错误!,请重新输入!"); 143 SimpleInterestCalculation(); 144 } 145 System.out.println("请输入存款年数:"); 146 years = scanner.next(); 147 if(isNumeric(years)) 148 { 149 Year = StringToInt(years); 150 } 151 else 152 { 153 System.out.println("输入错误!,请重新输入!"); 154 SimpleInterestCalculation(); 155 } 156 System.out.println("请输入年利率:"); 157 rate = scanner.next(); 158 if(isNumeric(rate)) 159 { 160 Rate = StringToDouble(rate); 161 } 162 else 163 { 164 System.out.println("输入错误!,请重新输入!"); 165 SimpleInterestCalculation(); 166 } 167 interest = Money*Rate*Year; 168 sum1 = Money+interest; 169 System.out.println("存入第" + Year + "年后的存款总额为:" + sum1); 170 main(null); 171 } 172 173 public static void PrincipalCalculation() 174 { 175 String ExpectedPrincipal,rate,years; 176 double Rate=0,ExpectedPrincipalMoney=0,money = 0; 177 int Year = 0; 178 System.out.println("预期金额"); 179 ExpectedPrincipal = scanner.next(); 180 if(isNumeric(ExpectedPrincipal)) 181 { 182 ExpectedPrincipalMoney = StringToDouble(ExpectedPrincipal); 183 } 184 else 185 { 186 System.out.println("输入错误!,请重新输入!"); 187 PrincipalCalculation(); 188 } 189 System.out.println("请输入存款年数:"); 190 years = scanner.next(); 191 if(isNumeric(years)) 192 { 193 Year = StringToInt(years); 194 } 195 else 196 { 197 System.out.println("输入错误!,请重新输入!"); 198 PrincipalCalculation(); 199 } 200 System.out.println("请输入年利率:"); 201 rate = scanner.next(); 202 if(isNumeric(rate)) 203 { 204 Rate = StringToDouble(rate); 205 } 206 else 207 { 208 System.out.println("输入错误!,请重新输入!"); 209 PrincipalCalculation(); 210 } 211 money = ExpectedPrincipalMoney/Math.pow(1.0 + Rate, Year); 212 System.out.println("初始本金为(复利算法)" + money); 213 money = ExpectedPrincipalMoney/(1+Rate*Year); 214 System.out.println("初始本金为(单利算法)" + money); 215 main(null); 216 } 217 218 public static void CalculateRewardTime() 219 { 220 double year = 0,ExpectedPrincipalMoney = 0,Rate = 0,Money = 0; 221 String ExpectedPrincipal,rate,money; 222 System.out.println("预期金额"); 223 ExpectedPrincipal = scanner.next(); 224 if(isNumeric(ExpectedPrincipal)) 225 { 226 ExpectedPrincipalMoney = StringToDouble(ExpectedPrincipal); 227 } 228 else 229 { 230 System.out.println("输入错误!,请重新输入!"); 231 CalculateRewardTime(); 232 } 233 System.out.println("请输入年利率:"); 234 rate = scanner.next(); 235 if(isNumeric(rate)) 236 { 237 Rate = StringToDouble(rate); 238 } 239 else 240 { 241 System.out.println("输入错误!,请重新输入!"); 242 CalculateRewardTime(); 243 } 244 System.out.println("本金"); 245 money = scanner.next(); 246 if(isNumeric(money)) 247 { 248 Money = StringToDouble(money); 249 } 250 else 251 { 252 System.out.println("输入错误!,请重新输入!"); 253 CalculateRewardTime(); 254 } 255 year = log((ExpectedPrincipalMoney/Money),1+Rate); 256 System.out.println("年份" + Math.ceil(year)); 257 main(null); 258 } 259 260 public static double log(double value,double base) 261 { 262 return Math.log(value)/Math.log(base); 263 } 264 265 public static void CalculateInterest() 266 { 267 double ExpectedPrincipalMoney = 0,Money = 0; 268 int Year = 0; 269 String ExpectedPrincipal,years,money; 270 double rate = 0; 271 System.out.println("预期金额"); 272 ExpectedPrincipal = scanner.next(); 273 if(isNumeric(ExpectedPrincipal)) 274 { 275 ExpectedPrincipalMoney = StringToDouble(ExpectedPrincipal); 276 } 277 else 278 { 279 System.out.println("输入错误!,请重新输入!"); 280 CalculateInterest(); 281 } 282 System.out.println("请输入年份:"); 283 years = scanner.next(); 284 if(isNumeric(years)) 285 { 286 Year = StringToInt(years); 287 } 288 else 289 { 290 System.out.println("输入错误!,请重新输入!"); 291 CalculateInterest(); 292 } 293 System.out.println("本金"); 294 money = scanner.next(); 295 if(isNumeric(money)) 296 { 297 Money = StringToDouble(money); 298 } 299 else 300 { 301 System.out.println("输入错误!,请重新输入!"); 302 CalculateInterest(); 303 } 304 rate = Math.pow((ExpectedPrincipalMoney/Money), 1/Year)-1; 305 System.out.println("利率" + rate); 306 main(null); 307 } 308 309 public static void IncreasingInterestInvestmentQuota() 310 { 311 System.out.println("每年定额选1,每月定额选2"); 312 String choice = scanner.next(); 313 if(isNumeric(choice)) 314 { 315 switch(StringToInt(choice)) 316 { 317 case 1: 318 EachYear(); 319 break; 320 case 2: 321 EachMonth(); 322 break; 323 } 324 } 325 else 326 { 327 System.out.println("输入错误!,请重新输入!"); 328 IncreasingInterestInvestmentQuota(); 329 } 330 } 331 332 public static void EachYear() 333 { 334 double EachYearQuotaMoney = 0,Rate = 0,sum1 = 0; 335 int Year = 0; 336 String years,EachYearQuotaMoney1,rate; 337 System.out.println("每年定额资本"); 338 EachYearQuotaMoney1 = scanner.next(); 339 if(isNumeric(EachYearQuotaMoney1)) 340 { 341 EachYearQuotaMoney = StringToDouble(EachYearQuotaMoney1); 342 } 343 else 344 { 345 System.out.println("输入错误!,请重新输入!"); 346 EachYear(); 347 } 348 System.out.println("请输入存款年数:"); 349 years = scanner.next(); // 存钱年数 350 if(isNumeric(years)) 351 { 352 Year = StringToInt(years); 353 } 354 else 355 { 356 System.out.println("输入错误!,请重新输入!"); 357 EachYear(); 358 } 359 System.out.println("请输入年利率:"); 360 rate = scanner.next(); 361 if(isNumeric(rate)) 362 { 363 Rate = StringToDouble(rate); 364 } 365 else 366 { 367 System.out.println("输入错误!,请重新输入!"); 368 EachYear(); 369 } 370 sum1 = EachYearQuotaMoney*(1+Rate)*(-1+Math.pow(1+Rate, Year))/Rate; 371 System.out.println("存入第" + Year + "年后的存款总额为:" + sum1); 372 main(null); 373 } 374 375 public static void EachMonth() 376 { 377 double EachMonthQuotaMoney1 = 0,MonthRate1 = 0,sum1 = 0; 378 int Months1 = 0; 379 String EachMonthQuotaMoney,MonthRate,Months; 380 System.out.println("每月定额资本"); 381 EachMonthQuotaMoney = scanner.next(); 382 if(isNumeric(EachMonthQuotaMoney)) 383 { 384 EachMonthQuotaMoney1 = StringToDouble(EachMonthQuotaMoney); 385 } 386 else 387 { 388 System.out.println("输入错误!,请重新输入!"); 389 EachMonth(); 390 } 391 System.out.println("请输入存款月数:"); 392 Months = scanner.next(); 393 if(isNumeric(Months)) 394 { 395 Months1 = StringToInt(Months); 396 } 397 else 398 { 399 System.out.println("输入错误!,请重新输入!"); 400 EachMonth(); 401 } 402 System.out.println("请输入月利率:"); 403 MonthRate = scanner.next(); 404 if(isNumeric(MonthRate)) 405 { 406 MonthRate1 = StringToDouble(MonthRate); 407 } 408 else 409 { 410 System.out.println("输入错误!,请重新输入!"); 411 EachMonth(); 412 } 413 sum1 = EachMonthQuotaMoney1*(1+MonthRate1)*(-1+Math.pow(1+MonthRate1, Months1))/MonthRate1; 414 System.out.println("存入第" + Months1 + "月后的存款总额为:" + sum1); 415 main(null); 416 } 417 418 public static void MatchingInterestRepaymentCalculator() 419 { 420 String money,rate,years; 421 double Money = 0,Rate = 0,interest,Repayment = 0,Repayment1 = 0,sum1 = 0,sum = 0; 422 int Year = 0; 423 System.out.println("请输入贷款金额数"); 424 money = scanner.next(); 425 if(isNumeric(money)) 426 { 427 Money = StringToDouble(money); 428 } 429 else 430 { 431 System.out.println("输入错误!,请重新输入!"); 432 MatchingInterestRepaymentCalculator(); 433 } 434 System.out.println("请输入贷款年限"); 435 years = scanner.next(); 436 if(isNumeric(years)) 437 { 438 Year = StringToInt(years); 439 } 440 else 441 { 442 System.out.println("输入错误!,请重新输入!"); 443 MatchingInterestRepaymentCalculator(); 444 } 445 System.out.println("请输入贷款年利率"); 446 rate = scanner.next(); 447 if(isNumeric(rate)) 448 { 449 Rate = StringToDouble(rate); 450 } 451 else 452 { 453 System.out.println("输入错误!,请重新输入!"); 454 MatchingInterestRepaymentCalculator(); 455 } 456 //复利 457 for (int i = 1; i <= Year; i++) 458 { 459 sum1 = Money*Math.pow(1.0 + Rate, Year); 460 } 461 Repayment = sum1/(Year*12); 462 interest = Money*Rate*Year; 463 sum = Money+interest; 464 Repayment1 = sum/(Year*12); 465 System.out.println("每月需要还款(单利)" + Repayment1); 466 System.out.println("每月需要还款(复利)" + Repayment); 467 } 468 }
旧版本没有提示