找到变量的平均值

时间:2015-02-01 17:45:46

标签: vb.net visual-studio

完全披露,我正在为COP2170进行任务,但附加功能并不仅仅是为了进一步扩展......

我试图添加5个测试分数并输出5个分数的平均值,该部分工作得很好。此外,我试图添加一个允许用户输入少于5分的附加功能,程序仍然会输出输入的任何分数的平均值。

这样可行:

enter image description here

这有效:

enter image description here

我遇到的问题是,如果省略第一个分数并填写其余分数,则不起作用:

enter image description here

这是我到目前为止所获得的代码:

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: http://stackoverflow.com/a/13504361/1947286
                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

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

2 个答案:

答案 0 :(得分:2)

你遇到的问题是Convert.ToDouble(txtBox.text)(带有空字符串,会使Convert抛出异常。

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

无论

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部分,然后你尝试计算平均值,但是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

这些论文没有任何价值,作为回报,这不符合您的要求

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)

答案 1 :(得分:1)

我建议您存储对数组中每个文本框的引用。你会在这个例子的最后看到原因。

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的常用方法是处理Validating事件,通常与error provider class提及的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