2016-03-18 3 views
1

Я пытаюсь написать программу, которая получает входной и выходной файл со списком монет и количеством этих монет.String Форматирование с деньгами

import java.io.*; 
import java.util.*; 

public class CookieJar { 
public static void cashingIn(File input, File output){ 
    try{ 
     Scanner in = new Scanner(input); 
     PrintWriter writ = new PrintWriter(output); 
     double sum = 0; 
     if(in.hasNext()){ 
     String next = in.nextLine(); 
     Scanner help = new Scanner(next); 
     while(in.hasNextLine()){ 
      int y = Integer.parseInt(next.substring(0, 1)); 
      if(next.contains("pennies")){ 
       sum += y*0.01; 
      } 
      if(next.contains("dimes")){ 
       sum += y*.1; 
      } 
      if(next.contains("quarters")){ 
       sum += y*.25; 
      } 
      if(next.contains("nickles")){ 
       sum += y*.05; 
      } 
      if(next.contains("penny")){ 
       sum += .01; 
      } 
      if(next.contains("dime")){ 
       sum += .1; 
      } 
      if(next.contains("nickle")){ 
       sum += .05; 
      } 
      if(next.contains("quarter")){ 
       sum += .25; 
      } 
      if(sum == 0){ 
       String find = String.format("%s", "You have no money in the jar"); 
       writ.println(find); 
      } 
      String fixer = String.format("$%sf", sum); 
      writ.println("You have " + fixer + " in the jar"); 
     } 
     help.close(); 
     } 
     else{ 
      String find = String.format("%s" , "You have no money in the jar"); 
      writ.println(find); 
     } 
      in.close(); 

      writ.close(); 
    }catch(IOException e){ 

    } 
} 
} 

Проблема, которую я имею с этим кодом является то, что у меня возникают проблемы получения количества монет из файла и убедитесь, что тип каждой монеты есть. Вот пример метода тестера, который я использую.

@Test 
public void test3() { 
    try { 
     // create file 
     File  input = folder.newFile("input.txt"); 
     File  output = folder.newFile("output.txt"); 

     PrintWriter write = new PrintWriter(input); 
     write.println("32 nickels"); 
     write.println(" 1"); 
     write.println(" nickel 42"); 
     write.println("quarters 1 penny"); 
     write.println("1 quarter 23 pennies 16"); 
     write.println(""); 
     write.println("dimes 1 dime 1 dime 1 dime 1 dime"); 
     write.close(); 

     // invoke program 
     CookieJar.cashingIn(input, output); 

     // verify file results 
     assertTrue ("Output file does not exist", output.exists()); 
     Scanner scan  = new Scanner(output); 
     String expected = "You have $14.64 in the jar"; 
     assertTrue ("Unexpected end of file: expected \"%s\"" + expected, scan.hasNext()); 
     String actual = scan.nextLine(); 
     assertEquals("Incorrect result", expected, actual); 
     assertFalse ("File contains more data than expected", scan.hasNext()); 
     scan.close(); 
    } 
    catch (IOException e) { 
     fail("No exception should be thrown"); 
    } 
} 

Я также должен сделать число с запятыми, если я войду в тысячи. Я, вероятно, не достаточно конкретна, чтобы помочь мне, поэтому, если вам нужно больше разъяснений, просто спросите. Спасибо за любую вашу помощь. Я так запутался в форме.

+2

Не используйте «double», чтобы представлять деньги, он не может точно представлять все значения (например, '0,1' не может быть представлен). Вместо этого используйте «BigDecimal». – Keppil

+0

«Проблема с этим кодом заключается в том, что у меня возникли проблемы с получением», может быть, вы можете быть более конкретным? Проблема может заключаться в том, что вы используете странную подстроку. –

+1

Строка, содержащая «четверти», также содержит «четверть», поэтому вы будете удваивать количество всех сумм (кроме пенни). –

ответ

1

Это своего рода расширенный комментарий, но после этого поможет вам решить проблему самостоятельно, я верю.

Хорошо, что у вас есть тест, но он и код проверяют/делают слишком много. Обработка строк и подсчет монет - это, по крайней мере, одна ответственность, а взаимодействие с файлами - это определенно другая ответственность. При тестировании обоих сразу ваши тесты будут сложными и медленными.

Применяя Single Responsibility Principle делает его легче и быстрее тест:

//The ONLY responsibility of this class is to keep count of coin strings it is given 
public class CookieJar { 
    private double sum = 0; //consider internally counting pennies with an int 

    public void addString(string next){ 
     int y = Integer.parseInt(next.substring(0, 1)); 
     if(next.contains("pennies")){ 
      sum += y*0.01; 
     } 
     //etc (but no code that reads/writes to console or files) 
    } 

    public string summarize(){ 
     if(sum == 0){ 
     return String.format("%s", "You have no money in the jar"); 
     } 
     String fixer = String.format("$%sf", sum); 
     return "You have " + fixer + " in the jar"; 
    } 
} 

Тесты будет намного проще писать и быстрее, вы можете легко проверить каждый тип монеты по отдельности в отдельных тестах, а затем проверить все вместе, когда все они работают:

@Test 
public void test3() { 
    CookieJar cookieJar = new CookieJar(); 

    cookieJar.addString("32 nickels"); 

    assertEquals("You have $1.60 in the jar", cookieJar.summarize()); 
} 

из кода файла выглядит проще:

//The ONLY responsibility of this class is to allow reading and writing of coin files 
public final class CookieJarIo { 

    private CookieJarIo(){} //static class 

    public static void cashingIn(File input, File output){ 
     try{ 
      Scanner in = new Scanner(input); 
      PrintWriter writ = new PrintWriter(output); 

      CookieJar cookieJar = new CookieJar(); //use our other class 

      if (in.hasNext()){ 
       String next = in.nextLine(); 
       Scanner help = new Scanner(next); 
       while(in.hasNextLine()){ 
       cookieJar.addString(next); 
       writ.println(cookieJar.summarize()); 
       } 
       help.close(); 
      } else { 
       writ.println(cookieJar.summarize()); 
      } 
      in.close(); 

      writ.close(); 
     } catch(IOException e){ 

     } 
    } 
} 
0

Вы должны внимательно рассмотреть ответ @ weston о разделении обязанностей.

Однако в этом коде вы можете заставить его работать, если вы заметили, что ожидаемый входной файл содержит поток, чередующий целое число и строку, например.

32 nickels 
1 
nickel 42 
quarters 1 penny 
1 quarter 23 pennies 16 

dimes 1 dime 1 dime 1 dime 1 dime 

Вы можете обнаружить и обработать маркеры в этой модели с Scanner in:

int amountInPennies = 0; 
while (in.hasNextInt()) { 
    int quantity = in.nextInt(); 

    if (!in.hasNext()) { 
    System.err.println("Didn't have a unit! Stopping."); 
    break; 
    } 
    String unit = in.next(); 

    switch (unit) { 
    case "penny": 
    case "pennies": 
     amountInPennies += 1 * quantity; 
     break; 
    case "nickel": 
    case "nickels": 
     amountInPennies += 5 * quantity; 
     break; 
    // etc. 
    } 
} 
BigDecimal amountInDollars = BigDecimal.valueOf(amountInPennies, -2); 
System.out.println("You have " + amount + " in the jar."); 

С точки зрения того, как форматировать сумму в качестве валюты, вы должны смотреть в NumberFormat.getCurrencyInstance()

Смежные вопросы