我怎么知道为什么我的程序计算和输出不正确?

时间:2011-03-24 17:23:03

标签: delphi debugging

我正在处理编程问题。

注意:这不是学生项目。我正在研究这个网站Try My Quest Dot Com的新任务,我是管理员。

问题:

Jenny刚刚开始担任Justine Java Workshop的程序员。她的报酬是10美元 一小时,除了少数例外。她每天工作超过8小时,每小时额外收取1.50美元,而在任何一周内,每小时额外收费2.50美元,超过40小时。此外,她在周六工作时获得125%的奖金,在周日工作获得50%的奖金。周六和周日的奖金根据当天的工作时数计算;他们不习惯计算一周工作超过40小时的任何奖金。您将获得Jenny每周工作的小时数(星期日,星期一等),您需要计算一周的工资。输入将为正整数,小于或等于24.输出必须使用美元符号格式化并向上舍入到最接近的便士。例如,$ 2"和$ 2.136666"是错的答案;正确的版本是$ 2.00"和$ 2.14"分别。

无论如何,我试图用Delphi(无表格项目)写这个。我传递了一个命令行参数 - timecard.dat

输入

0, 8, 8, 8, 8, 8, 0
0, 10, 10, 10, 10, 10, 0
0, 0, 8, 8, 8, 8, 8
0, 0, 0, 10, 10, 10, 10
10, 10, 10, 9, 9, 9, 9

输出

Output #1: $400.00
Output #2: $540.00
Output #3: $500.00
Output #4: $540.75
Output #5: $905.88
然而,

我的出局是:

Output #1: $400.00
Output #2: $540.00
Output #3: $500.00

Output #4: $537.00
Output #5: $902.50

我的最后两个输出值与实际结果不同。不知道为什么,我越是盯着代码,我就越少看到它

谁能告诉我我做错了什么?

program ACSL_Time_Cards;
{assumes Sunday = 1, Monday 3, etc}
uses
  SysUtils,
  Dialogs;

const
 HourlyWage = 10.00;
 OverEightWage = 1.50;
 OverFortyWage = 2.50;
var
 F: TextFile;
 I, ArrayIndex: Integer;
 WeeklyHours: Array[0..6] of Integer; //weekly hours
 HourStr, LineStr: String;
 TotalHours, TotalOverFortyHours, TotalOverEightHours, TotalSatHours, TotalSunHours: Integer;
 TotalWages: Real;
begin
 //initialize variables
 TotalHours:= 0;
 TotalOverEightHours:= 0;
 TotalOverFortyHours:= 0;
 TotalSatHours:= 0;
 TotalSunHours:= 0;
 TotalWages:= 0.00;
 ArrayIndex:= 0;
 //open file "timecard.dat" for input
 if FileExists(ParamStr(1)) then
 begin
  AssignFile(F, ParamStr(1));
  Reset(F);
  //step through file and extract each line and store in hoursStr
  while not EOF(F) do
  begin
   Readln(F, LineStr);
   //step through hours string and fill Array with weekly hours
   for I:= 1 to length(LineStr) do
   begin
    //if character is not a ',' then add it to hourStr
    if LineStr[I] <> ',' then
     HourStr:= HourStr + LineStr[I]
    else
    begin
     //add HourStr to Array
     WeeklyHours[ArrayIndex]:= StrToInt(HourStr);
     //reset the variable
     HourStr:= '';
     //increment Variable
     Inc(ArrayIndex);
    end; //else
   end; //for I:= 1 to length(HoursStr) do
   //clean up by adding the last remaining one
   WeeklyHours[ArrayIndex]:= StrToInt(HourStr);
   //step through array and figure out overtime Daily and Weekly
   for I:= Low(WeeklyHours) to High(WeeklyHours) do
   begin
    TotalHours:= TotalHours + WeeklyHours[I];
    if WeeklyHours[I] > 8 then
     TotalOverEightHours:= TotalOverEightHours + WeeklyHours[I]-8;
     //get sunday hours
     if I + 1 = 1 then
      TotalSunHours:= TotalSunHours + WeeklyHours[I];
     //get saturday hours
     if I + 1 = 7 then
     TotalSatHours:= TotalSatHours + WeeklyHours[I];
   end;
   //get total over 40 hours
   if TotalHours > 40 then
    TotalOverFortyHours:= TotalHours-40;
  //compute Regular Hours
  TotalWages:= TotalWages + TotalHours * 10.00;
  //compute overtime hours

  TotalWages:= TotalWages + TotalOverEightHours * 1.50;
  TotalWages:= TotalWages + TotalOverFortyHours * 2.50;
  //compute bonuses
  TotalWages:= TotalWages + (TotalSatHours * 10.00) * 1.25;
  TotalWages:= TotalWages + (TotalSunHours * 10.00) * 0.50;

  ShowMessage('TotalWages: ' + FormatFloat('$0.00', TotalWages));
  //reset variables
  TotalWages:= 0.00;
  TotalHours:= 0;
  TotalOverEightHours:= 0;
  TotalOverFortyHours:= 0;
  TotalSatHours:= 0;
  TotalSunHours:= 0;
  HourStr:= '';
  ArrayIndex:= 0;
  end; //while not EOF(F) do
  CloseFile(F);
 end
 else
 ShowMessage('File does not exist!');
end.

我确信有很多方法可以更好地编写。我真的只是对我的价值观与预期值不同的原因感兴趣。谢谢!

3 个答案:

答案 0 :(得分:6)

代码将受益于I / O和分离的计算。你的问题与计算有关。我写的是这样的:

uses
  Math;

type
  TDay = (
    daySunday,
    dayMonday,
    dayTuesday,
    dayWednesday,
    dayThursday,
    dayFriday,
    daySaturday
  );
  TDayArray = array [TDay] of Integer;

function Wage(const Hours: TDayArray): Double;
const
  BasicRate = 10.0;
  DailyOvertimeRate = 1.5;
  WeeklyOvertimeRate = 2.5;
  DailyOvertimeThreshold = 8;
  WeeklyOvertimeThreshold = 40;
  DailyBonus: array [TDay] of Double = (1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 2.25);
var
  Day: TDay;
  DailyOvertimeHours, WeeklyOvertimeHours, TotalHours: Double;
  DailyPay: array [TDay] of Double;
begin
  TotalHours := 0.0;
  for Day := low(Day) to high(Day) do begin
    TotalHours := TotalHours + Hours[Day];
    DailyOvertimeHours := Max(Hours[Day]-DailyOvertimeThreshold, 0.0);
    DailyPay[Day] := Hours[Day]*BasicRate;
    DailyPay[Day] := DailyPay[Day] + DailyOvertimeHours*DailyOvertimeRate;
    DailyPay[Day] := DailyPay[Day]*DailyBonus[Day];
  end;
  WeeklyOvertimeHours := Max(TotalHours-WeeklyOvertimeThreshold, 0.0);
  Result := Sum(DailyPay) + WeeklyOvertimeHours*WeeklyOvertimeRate;
end;

这仍然有点粗糙,我对薪酬,加班等变量名称不太满意。

一旦有了这样的实用程序功能,那么将它与程序的其余部分放在一起就会变得容易多了。

您当前计划中最大的弱点是一切都在一个巨大的例程中。把它分解成小块,你就能比在一个大型例程中找到问题更容易验证这些小块。

答案 1 :(得分:6)

对于像这样的简单问题,您可能希望手动编写,然后查看您的代码是否遵循您所执行的相同步骤。

对于输出4,星期六的125%奖金不包括8小时后每小时1.50美元的额外费用:

她应该赚

Wed: $103    | $100 for 10 hours plus $3 for 2 hours over 8
Thu: $103    | $100 for 10 hours plus $3 for 2 hours over 8
Fri: $103    | $100 for 10 hours plus $3 for 2 hours over 8
Sat: $231.75 | ($100 for 10 hours, $3 for 2 hours over 8), $128.75 for 125% bonus

总计540.75

答案 2 :(得分:3)

通过学习How to debug a Delphi program来自行查找。

注意这些部分:

手表 - 在步进或跟踪代码时添加监视以跟踪程序变量或表达式的值。
断点 - 按下F5按钮或单击编辑器中的左侧栏时,可以在源中添加红线。这行源将有一个断点。运行程序时,执行将在通过源代码行时停止。现在,您可以使用一些功能键跟踪源代码。