?
Solved

adding to a dictionary within a function

Posted on 2014-02-02
21
Medium Priority
?
311 Views
Last Modified: 2014-02-04
How can i add to a dictionary within a class?


i call the dictionary under the partial class

Partial Class football_home
    Inherits System.Web.UI.Page

    Dim dictionary As New Dictionary(Of String, String)

Open in new window


and i can add to the dictionary under page_load like this

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load



        dictionary.Add("Dot2", "Dot2")
        dictionary.Add("Dot3", "Dot3")
    End Sub

Open in new window



but if i try adding it under function it doe snot work
Function setscores() As String
      
        dictionary.Add("Dot4", "Dot4")
        Dim thescorestext As String

Open in new window



so i run  
Dim pair As KeyValuePair(Of String, String)
        For Each pair In Dictionary
            ' Display Key and Value.
            scorestext.Text += pair.Key & " .. " & pair.Value & dictionary.Count & "<br>"
        Next

Open in new window



and it displays dot2 dot3 but not dot 4?
0
Comment
Question by:runnerjp2005
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 12
  • 8
21 Comments
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39828116
Is the Function setscores in the same scope that the Page_Load is in?
0
 

Author Comment

by:runnerjp2005
ID: 39828178
yes it is
Imports System.Net 
Imports System.IO 
Imports HtmlAgilityPack

Partial Class football_home
    Inherits System.Web.UI.Page

    Dim dictionary As New Dictionary(Of String, String)


    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load



        dictionary.Add("Dot2", "Dot2")
        dictionary.Add("Dot3", "Dot3")
    End Sub


    Function setscores() As String
        Dim dictionary As Dictionary(Of String, String)
        dictionary.Add("Dot4", "Dot4")

Open in new window

0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39828252
In the function setscores remove the first line of code

Dim dictionary As Dictionary(Of String, String)

It will hide the one defined in class level
0
Docker-Compose to Simplify Multi-Container Builds

Our veteran DevOps Author takes you through how to build a multi-container environment, managed with a single utility in order to simplify your deployments.

 

Author Comment

by:runnerjp2005
ID: 39828419
even when i remove it , it does not add no4 ?
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39828458
If the project is not too big can you zip up the complete project and post it some where on the web where we can download it. If it is too big can you create a small test project that reproduces the same issue and post that some where I can download it to test.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39828711
Where are you calling the setscores method? If you don't call it, then it won't add 4 to the dictionary.
0
 

Author Comment

by:runnerjp2005
ID: 39829187
When I do call Setscores with add dictionary.Add("Dot4", "Dot4") - set scores returns nothing. when i remove add dictionary.Add("Dot4", "Dot4") from set scores it works ???
Below as all the code for this

home.aspx.vb
Imports System.Net 
Imports System.IO 
Imports HtmlAgilityPack

Partial Class football_home
    Inherits System.Web.UI.Page

    Dim dictionary As New Dictionary(Of String, String)


    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load



        dictionary.Add("Dot2", "Dot2")
        dictionary.Add("Dot3", "Dot3")
    End Sub


    Function setscores() As String

        Dim thescorestext As String
        Dim webGet As New HtmlWeb() 'open the system
        Dim htmlDoc As HtmlDocument = webGet.Load("http://www.livefutbol24.com/Football/Live") '' get the html from the webpage

        For Each div As Object In htmlDoc.DocumentNode.SelectNodes(".//div[@class='matches']") ' select all the divs within the code that contain *

            If Not div.selectSingleNode(".//td[@class='score']") Is Nothing Then

                Dim Scoresplit() As String = div.selectSingleNode(".//td[@class='score']").InnerText.Split("-") 'split the string for scores

                thescorestext += div.selectSingleNode(".//td[@class='time']").InnerText.Trim().Substring(0, 2) & "" 'set the time
                thescorestext += StringOutNumbers(div.selectSingleNode(".//td[@class='home']").InnerText) 'get home team name

                ' lblHTMLOutput.Text += mostused.gettheteams(StringOuttext(div.selectSingleNode(".//td[@class='home]").InnerText)) -redcard?

                'set the score with 0 being home team and 1 being away
                thescorestext += mostused.getscore(Scoresplit(0).Trim()) & " - " & mostused.getscore(Scoresplit(1).Trim())

                '  lblHTMLOutput.Text += mostused.gettheteams(StringOuttext(div.selectSingleNode(".//td[@class='away']").InnerText))

                thescorestext += StringOutNumbers(div.selectSingleNode(".//td[@class='away']").InnerText) ' get away teams name


                If Scoresplit(0).Trim() Or Scoresplit(1).Trim() <> "0" Then
                    thescorestext += DateAndTime.Now() & "<font size='3' color='orange'>Boom!</font> <br>"
                Else
                    thescorestext += DateAndTime.Now() & "<br>"
                End If

 dictionary.Add("Dot4", "Dot4")

            End If

        Next
   

        Return thescorestext
    End Function

    'this function will strip out any number from the text - needs adding to a class

    Function StringOutNumbers(ByVal HotStripper As String) As String
        Dim NewValue As String = ""
        For I As Integer = 0 To HotStripper.Length - 1
            If IsNumeric(HotStripper.Substring(I, 1)) = False Then
                NewValue += HotStripper.Substring(I, 1)
            End If
        Next
        Return NewValue
    End Function

    'this function will strip out any text from the text to leave numbers - needs adding to a class

    Function StringOuttext(ByVal HotStripper As String) As String
        Dim NewValue As String = ""
        For I As Integer = 0 To HotStripper.Length - 1
            If IsNumeric(HotStripper.Substring(I, 1)) = True Then
                NewValue += HotStripper.Substring(I, 1)
            End If
        Next
        Return NewValue
    End Function

   
    Protected Sub UpdateTimer_Tick(sender As Object, e As EventArgs) Handles UpdateTimer.Tick
	scorestext.Text = setscores()
            'Dim pair As KeyValuePair(Of String, String)
      'For Each pair In Dictionary
            ' Display Key and Value.
           'scorestext.Text = pair.Key & " .. " & pair.Value & dictionary.Count & "<br>"
        ' Next


    End Sub
End Class

Open in new window


Home.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="home.aspx.vb" Inherits="football_home" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
<h1>Screen Scrape </h1>
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
        <asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
            <Triggers>
                <asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
            </Triggers>
            <ContentTemplate>
               
<asp:label id="scorestext" runat="server" />
<asp:label id="scorestext2" runat="server" />
            </ContentTemplate>
        </asp:UpdatePanel>
  

    </form>
</body>
</html>

Open in new window


Mostused.vb  (This is a class)

¿Imports Microsoft.VisualBasic

Public Class mostused

    Shared Function getscore(ByVal thescore As String) As String

        Dim scoreoutput As String = ""


        If thescore <> "0" Then
            scoreoutput += "<font size='3' color='green'>" & thescore & "</font>"
        Else
            scoreoutput += "<font size='3' color='red'>" & thescore & "</font>"
        End If



        Return scoreoutput
    End Function

    Shared Function gettheteams(ByVal thesides As String) As String

        Dim thesidesare As String = ""

        If thesides <> "0" Then
            thesidesare = thesides
        End If
        Return thesidesare
    End Function


End Class

Open in new window

0
 

Author Comment

by:runnerjp2005
ID: 39829215
To add to the above to make it makes sense why im using dictionary - im going to add thescorestext to the dictionary like so -
dictionary.Add(thescorestext, div.selectSingleNode(".//td[@class='time']").InnerText.Trim().Substring(0, 2))

Open in new window


I was using the dot4 to find out where the code was breaking :)
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39829793
Hi runnerjp2005;

I suspect that the reason you are always seeing 2 entries in the dictionary and that "DOT4" is never there is that each time the page loads it has been reinitializing the dictionary to no entry and in page load putting the 2 entries back in. You need to check if it is a post back and if it is not initialize the  dictionary and if it is a post back refill the dictionary with previous values. As seen below. You also need to save the dictionary before PreRender to have the values available to be reloaded into the dictionary. Also if you attempt to load an entry into the dictionary with a key that already exist it will throw an exception.

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    ' In the Page_Load event you need to check if it is a post back. 
    ' If it is an initial load then add the two dictionary values other 
    ' wise restore the values in the dictionary with its previous values. 
    If Not Page.IsPostBack Then
        ' Initial load of dictionary
        dictionary.Add("Dot2", "Dot2")
        dictionary.Add("Dot3", "Dot3")
    Else
        ' Get the previous values of the dictionary and restore it to the variable
        dictionary = CType(Me.ViewState("ScoreDictionary"), Dictionary(Of String, String))
    End If

End Sub



Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs)
    ' Save dictionary before the page is rendered.
    ' to be re-loaded on the next page request
    Me.ViewState.Add("ScoreDictionary", dictionary)
End Sub

Function setscores() As String

     Dim thescorestext As String
     Dim webGet As New HtmlWeb() 'open the system
     Dim htmlDoc As HtmlDocument = webGet.Load("http://www.livefutbol24.com/Football/Live") '' get the html from the webpage

     For Each div As Object In htmlDoc.DocumentNode.SelectNodes(".//div[@class='matches']") ' select all the divs within the code that contain *

         If Not div.selectSingleNode(".//td[@class='score']") Is Nothing Then

             ' You other code here .....
             
             ' Because this is the same value being loaded each time this function
             ' is called it will throw an exception if it is already there. So check to see if it is 
             ' already there before adding.
             If Not dictionary.ContainsKey("Dot4") Then
                 dictionary.Add("Dot4", "Dot4")
             End If

         End If

     Next

     Return thescorestext

End Function    

Open in new window

0
 

Author Comment

by:runnerjp2005
ID: 39831079
Hi,

I took ll the advice above and with using the page load and not the update ticker it works fine.... bbut when i add it to the update ticker it does nothing... the diconary does not seem to work on the update ticker


 Protected Sub UpdateTimer_Tick(sender As Object, e As EventArgs) Handles UpdateTimer.Tick
        If Not Page.IsPostBack Then
            ' Initial load of dictionary
            dictionary.Add("Dot2", "Dot2")
            dictionary.Add("Dot3", "Dot3")
        Else
            '    ' Get the previous values of the dictionary and restore it to the variable
            dictionary = CType(Me.ViewState("ScoreDictionary"), Dictionary(Of String, String))
        End If

        'setscores()
        Dim pair As KeyValuePair(Of String, String)
        For Each pair In dictionary
            ' Display Key and Value.
            test.Text += pair.Key
        Next
        'test.Text = "hello454"
    End Sub

Open in new window

0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39831534
First this code really belongs in the Page_Load and NOT in the timer.

If Not Page.IsPostBack Then
    ' Initial load of dictionary
    dictionary.Add("Dot2", "Dot2")
    dictionary.Add("Dot3", "Dot3")
Else
    '    ' Get the previous values of the dictionary and restore it to the variable
    dictionary = CType(Me.ViewState("ScoreDictionary"), Dictionary(Of String, String))
End If

Open in new window

Second you need to use the Page_PreRender event so that the dictionary is saved between post backs otherwise the dictionary will be empty.
0
 

Author Comment

by:runnerjp2005
ID: 39831921
I have added the code into page load and also the pre_render is always there... and the page is still blank :S


¿
Imports System.Net
Imports System.IO
Imports HtmlAgilityPack

Partial Class football_test
    Inherits System.Web.UI.Page

    Dim dictionary As New Dictionary(Of String, String)


    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        ' In the Page_Load event you need to check if it is a post back. 
        ' If it is an initial load then add the two dictionary values other 
        ' wise restore the values in the dictionary with its previous values. 
       If Not Page.IsPostBack Then
            ' Initial load of dictionary
            dictionary.Add("Dot2", "Dot2")
            dictionary.Add("Dot3", "Dot3")
        Else
            '    ' Get the previous values of the dictionary and restore it to the variable
            dictionary = CType(Me.ViewState("ScoreDictionary"), Dictionary(Of String, String))
        End If


    End Sub




    Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs)
        ' Save dictionary before the page is rendered.
        ' to be re-loaded on the next page request
        Me.ViewState.Add("ScoreDictionary", Dictionary)
    End Sub


    Function setscores() As String

        Dim thescorestext As String = ""
        Dim webGet As New HtmlWeb() 'open the system
        Dim htmlDoc As HtmlDocument = webGet.Load("http://www.livefutbol24.com/Football/Live") '' get the html from the webpage

        For Each div As Object In htmlDoc.DocumentNode.SelectNodes(".//div[@class='matches']") ' select all the divs within the code that contain *

            If Not div.selectSingleNode(".//td[@class='score']") Is Nothing Then

                ' You other code here .....

                ' Because this is the same value being loaded each time this function
                ' is called it will throw an exception if it is already there. So check to see if it is 
                ' already there before adding.
                Dim Scoresplit() As String = div.selectSingleNode(".//td[@class='score']").InnerText.Split("-") 'split the string for scores

                thescorestext += div.selectSingleNode(".//td[@class='time']").InnerText.Trim().Substring(0, 2) & "" 'set the time
                thescorestext += StringOutNumbers(div.selectSingleNode(".//td[@class='home']").InnerText) 'get home team name

                ' lblHTMLOutput.Text += mostused.gettheteams(StringOuttext(div.selectSingleNode(".//td[@class='home]").InnerText)) -redcard?

                'set the score with 0 being home team and 1 being away
                thescorestext += mostused.getscore(Scoresplit(0).Trim()) & " - " & mostused.getscore(Scoresplit(1).Trim())

                '  lblHTMLOutput.Text += mostused.gettheteams(StringOuttext(div.selectSingleNode(".//td[@class='away']").InnerText))

                thescorestext += StringOutNumbers(div.selectSingleNode(".//td[@class='away']").InnerText) ' get away teams name


                If Scoresplit(0).Trim() Or Scoresplit(1).Trim() <> "0" Then
                    thescorestext += DateAndTime.Now() & "<font size='3' color='orange'>Boom!</font> <br>"
                Else
                    thescorestext += DateAndTime.Now() & "<br>"
                End If





                If Not dictionary.ContainsKey(thescorestext) Then
                    dictionary.Add(thescorestext, "Dot4")
                End If

            End If

        Next

        Return thescorestext

    End Function

    Function StringOutNumbers(ByVal HotStripper As String) As String
        Dim NewValue As String = ""
        For I As Integer = 0 To HotStripper.Length - 1
            If IsNumeric(HotStripper.Substring(I, 1)) = False Then
                NewValue += HotStripper.Substring(I, 1)
            End If
        Next
        Return NewValue
    End Function

    'this function will strip out any text from the text to leave numbers - needs adding to a class

    Function StringOuttext(ByVal HotStripper As String) As String
        Dim NewValue As String = ""
        For I As Integer = 0 To HotStripper.Length - 1
            If IsNumeric(HotStripper.Substring(I, 1)) = True Then
                NewValue += HotStripper.Substring(I, 1)
            End If
        Next
        Return NewValue
    End Function

    Protected Sub UpdateTimer_Tick(sender As Object, e As EventArgs) Handles UpdateTimer.Tick
        
        setscores()
        Dim pair As KeyValuePair(Of String, String)
        For Each pair In dictionary
            ' Display Key and Value.
            test.Text += pair.Key
        Next
        'test.Text = "hello454"
    End Sub
End Class

Open in new window

0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39832227
Place a breakpoint in Page_PreRender to see if it is being called.
0
 

Author Comment

by:runnerjp2005
ID: 39832493
yup its been called
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 39832544
So it is being call, "Place a breakpoint in Page_PreRender to see if it is being called.", if that is the case and in that call it is saving the dictionary to the ViewState then I would need to run the code myself to see what is going on. If the project is not big can you please zip up the complete project into a zip file and upload it to the web some where that I can download it. If that is not possible please create a test project showing the issue that you are having so I can have a look at it and zip it up to the web so that I can download it to test.
0
 

Author Comment

by:runnerjp2005
ID: 39832553
OK will do it @ around 5:30ish :D
0
 

Author Comment

by:runnerjp2005
ID: 39832747
OK managed to get them uploaded (attached)

Also note it uses http://htmlagilitypack.codeplex.com/
test.aspx.vb
test.aspx
mostused.vb
0
 

Author Comment

by:runnerjp2005
ID: 39832754
What it should be doing the loading setscores() and checking the html... adding them into the Dictionary if its not already in then displaying the dictionary results in the timer....or

setscores()
        Dim pair As KeyValuePair(Of String, String)
        For Each pair In dictionary
             'Display Key and Value.
            test.Text += pair.Key
        Next
0
 

Author Comment

by:runnerjp2005
ID: 39832773
Sorry also noted in test.aspx.vb line test2.text = ball should be commented out
0
 
LVL 63

Accepted Solution

by:
Fernando Soto earned 2000 total points
ID: 39832820
Hi runnerjp2005;

Sorry, but when I asked you to, "please zip up the complete project ", what I needed you to do is use a zip compression program and zip up the main project folder which will zip ALL files in that folder into one zip file. Sometimes project settings can cause issues we will not be able to find those issues by just seeing a couple of files.

Looking at the web page file I noticed that  AutoEventWireup is set to false, see below code snippet. For Page_PreRender to be called this value needs to be set to true. Try making AutoEventWireup="false" to AutoEventWireup="true" and see what happens.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test.aspx.vb" Inherits="football_test" %>

Open in new window

0
 

Author Closing Comment

by:runnerjp2005
ID: 39833112
Brill thanks works great - thankyou for your help
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question