找到变量的平均值

find average of variables

完全公开,我正在为 COP2170 做一项作业,但附加功能不属于作业的一部分,只是想进一步延伸......

我正在尝试添加 5 个测试分数并输出 5 个分数的平均值,这部分工作正常。此外,我正在尝试添加一项附加功能,允许用户输入少于 5 分的分数,并且程序仍将输出输入的任何分数的平均值。

所以这有效:

这有效:

我 运行 遇到的问题是,如果第一个分数被省略而其余的都被填写,它就不起作用:

这是我目前得到的代码:

Public Class frmTestScoreAverage


    Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
        Dim decScore1, decScore2, decScore3, decScore4, decScore5 As Double ' decScore1-5 to hold test scores1-5
        Dim decScoreAverage As Double ' to hold test score average
        Dim intDivideBy As Double = 5 ' declare intDivideBy variable with starting value of 5 

        lblStatusLabel.Text = String.Empty 'set error message to empty string

        Try
            ' Read user input convert to double and assign value to variable
            decScore1 = Convert.ToDouble(txtScore1.Text)
            decScore2 = Convert.ToDouble(txtScore2.Text)
            decScore3 = Convert.ToDouble(txtScore3.Text)
            decScore4 = Convert.ToDouble(txtScore4.Text)
            decScore5 = Convert.ToDouble(txtScore5.Text)

            ' Calculate average
            decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy

            'display result
            lblResult.Text = CStr(decScoreAverage)

        Catch
            ' Display error message, asks for all scores
            lblStatusLabel.Text = "Please enter all test scores"

            'Calculate average even without all scores 
            For Each c As TextBox In Me.Controls.OfType(Of TextBox)() 'loop through each textbox in form see: 
                If c.Text = String.Empty Then intDivideBy -= 1 'If text equals empty string, Then decrement intDivideBy
            Next

            'catch divide by zero error
            Try
                'calculate average
                decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy 'add test scores and divide to find average

                'display result
                lblResult.Text = CStr(decScoreAverage)
            Catch
                lblStatusLabel.Text = "Please enter at least one test score"
            End Try

        End Try
    End Sub

End Class

我很确定问题与我求平均值的方式有关:

decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy

有没有办法找到允许任何排列中的空变量的平均值?

您遇到的问题是 Convert.ToDouble(txtBox.text)(使用空字符串,将使 Convert 抛出异常。

添加字符串不为空的验证或使用 TryParse 查看文本框值是否可解析为数字。

两者都

If not String.IsNullOrEmpty(txtBox.Text) then
   Convert.ToDouble(txtBox.text)

 dim value as Double
 if Double.TryParse(txtBox.Text, value) then
     avg += value

当第一个为空时,它转到代码的 Catch 部分,然后您尝试计算 avg,但是 Txtbox 的值未分配给您所做的声明,因此当它尝试取平均值

    decScore1 = Convert.ToDouble(txtScore1.Text) // Exception here to Catch
    decScore2 = Convert.ToDouble(txtScore2.Text) // Not evaluated
    decScore3 = Convert.ToDouble(txtScore3.Text) // Not evaluated
    decScore4 = Convert.ToDouble(txtScore4.Text) // Not evaluated
    decScore5 = Convert.ToDouble(txtScore5.Text) // Not evaluated

论文没有任何价值,return这不是你想要的

decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy

更新 (Vb 代码未测试)

Function GetTextValue(dim score as string) as Double
    dim value as Double = 0

    if (Double.TryParse(score, value)) 
        return value
    else
        return value

End Function

这个

decScore1 = Convert.ToDouble(txtScore1.Text)

变成

decScore1 = GetTextValue(txtScore1.Text)

我建议您将对每个文本框的引用存储在一个数组中。您将在本示例的末尾看到原因。

Public Class frmTestScoreAverage

    Public Sub New()
        Me.InitializeComponent()
        Me.boxes = {Me.txtScore1, Me.txtScore2, Me.txtScore3, Me.txtScore4, Me.txtScore5}
    End Sub

    Private boxes As TextBox()

validate user input in winforms is to handle the Validating event, usually combined with the error provider class as mentioned by Hans Passant的常用方法。

    Private Sub HandleScoreValidating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles txtScore1.Validating, txtScore2.Validating, txtScore3.Validating, txtScore4.Validating, txtScore5.Validating
        With DirectCast(sender, TextBox)
            If ((Not String.IsNullOrEmpty(.Text)) AndAlso (Not Double.TryParse(.Text, 0.0R))) Then
                e.Cancel = True
                'Alert or set error provider:
                'Me.ErrorProvider1.SetError(DirectCast(sender, Control), "Not double")
            Else
                e.Cancel = False
                'Clear error provider:
                'Me.ErrorProvider1.Clear()
            End If
        End With
    End Sub

现在,回到文本框数组。创建一个新的 double 列表并迭代文本框数组。如果文本不为空,则解析值并将其添加到列表中。最后,使用Average扩展方法取平均值。

    Private Sub HandleCalculate(sender As Object, e As EventArgs) Handles btnCalculate.Click

        Dim values As New List(Of Double)

        For Each box As TextBox In Me.boxes
            If (Not String.IsNullOrEmpty(box.Text)) Then
                values.Add(Double.Parse(box.Text))
           'Else
            '    values.Add(0.0R)
            End If
        Next

        Dim average As Double = values.Average()

        '....

    End Sub

End Class