FIFO let's play.

IanMc

Well-Known Member
Licensed User
Longtime User
FIFO comes from ye olde English song 'Fee FIFO Fumb, I smell the blood of an English Mon'

Arrays ay? and their crazy 'out of bounds' way of crashing the entire system, a programmers bane since days of yore.

There is probably a really neat way of putting this into an object and calling it something like, oh I don't know, FIFO maybe?

Then you could create a new instance of the FIFO object, give it a name and reference its elephants.. i mean elements.

However just for playing (and to cover up the fact that I don't know how to do the above obectifyin') here's how to do it prehistorically.

Just for testing I created a new project, went into the designer and put three buttons on and called em'

fill
print
fifo

then I added the click members, which you can just do by hand in your Main code thusly:

Sub fill_Click

End Sub

Sub print_Click

End Sub

Sub fifo_Click

End Sub

In my Sub Process_Globals I have
Dim smsFifo as List

then in my Sub Activity_Create(FirstTime as Boolean) I have
If FirstTime Then
smsFifo.Initialize
End If
And don't forget your Activity.LoadLayout("Test") 'I called mine Test ....

I put the smsFifo.Initialize in that If clause because it would seem that Activity_Create is not always called only once and if I
don't then my List might get randomly initilized and thusly cleared.

The reason I want a FIFO (First In First Out) list is because I'm writing a routine that will capture an incoming SMS text message where the first word in the message should be a password, if it matches then that message is nabbed and prevented from going further on to the messaging app and the rest of the message is split up into 'commands' where the split delimiter is the semi-colon so for testing and to represent the incoming SMS text here is a string of stringyness:

Dim s As String = " Bti say Hello how are you?; well here we go; this is another string; sfx2"

so here 'Bti' is the first word in the text and if this matches the 'password' then the text will be nabbed etc. etc. etc. then the rest of the message will be split up into 'commands', put into a FIFO list then dealt with by another routine (activated by a timer) as and when it is convenient. A sort of computerized bureaucracy :) where the FIFO list can be added to at any time.

So here's the code. All the testing is done by writing to the log so have the log screen cleared and in view.
I'm sure it can be done more elegantly than this but I'm still a relative newbie to B4A and its all good learning.
Let me know what you think and feel free to chop and change it about etc.
B4X:
Sub FIFO As String
   Dim s As String
   Try
      s = smsFifo.Get(0)
      smsFifo.RemoveAt(0)
      Return s
   Catch
      Log("Kabooom!")
   End Try
   Return "" 'don't need an ELSE IF because if it Returns s then it doesn't get this far.
   'in fact don't need a Return "" either because it either returns something or it crashes :)
End Sub


Sub fill_Click
   Dim theMagicWord As String = "bTi"
   Dim s As String = "       Bti say Hello how are you?; well here we go; this is another string; sfx2"
   s = s.Trim
   If s.ToLowerCase.Trim.StartsWith(theMagicWord.ToLowerCase.Trim) Then ' its one for us otherwise let it go.
      Dim parts() As String 'Will also clear it right?
      parts = Regex.Split(";", s)
      parts(0) = parts(0).SubString(theMagicWord.Length)
      For Each j As String In parts
         Log(j.Trim)
         smsFifo.Add(j) 'add it to the list baby! but don't clear it, add more if needed.
      Next
      Log("smsFifo Size = " & smsFifo.Size)
   Else
      Log("Nope, not one for us")
   End If
End Sub

Sub print_Click
   logspace 'print a few blank lines in the log to make it a little easier to read.
   Log("List Print")
   For Each s As String In smsFifo
      Log(smsFifo.IndexOf(s) & " " & s) 'so I want to print out the list element number and then whatever is in that list element.
   Next   
End Sub

Sub fifo_Click
   Dim s As String = FIFO
   If s <> "" Then 
      Log("FIFO Returned: " & s)
   Else
      Log("nah, FIFO returned an empty string")
   End If
End Sub

Sub logspace 'just to print a few blank lines in the log for easy reading
   For a = 1 To 4
      Log(" ")
   Next
End Sub
 
Last edited:

IanMc

Well-Known Member
Licensed User
Longtime User
Ok, not sure what I'm doing wrong here.

The fill subroutine adds the lines of text again to the list so when I press it three times I have 12 lines in my List but when I print those lines out using my print sub:
B4X:
Sub print_Click
   logspace
   Log("List Print")
   For Each s As String In smsFifo
      Log(smsFifo.IndexOf(s) & " " & s) 'so I want to print out the list element number and then the element
   Next
   
End Sub

I get:

List Print
0 say Hello how are you?
1 well here we go
2 this is another string
3 sfx2
0 say Hello how are you?
1 well here we go
2 this is another string
3 sfx2
0 say Hello how are you?
1 well here we go
2 this is another string
3 sfx2

Where the element numbers are recycling? I would have expected them to be numbered from 0 to 11?
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
It's because they are identical strings, so only the first matched element will be printed.
I think that you should loop through all contents of your list, instead of using for...each.
 
Upvote 0

IanMc

Well-Known Member
Licensed User
Longtime User
I don't really understand that, are you saying that in this case

For Each

really means

For Each unless there is one the same and then just show that one again?

I would like to understand exactly where I'm going wrong here just in case I ever want to use For Each again in the future :)

As we can see there are 12 elements in the List after pressing the fill button 3 times:
B4X:
say Hello how are you?
well here we go
this is another string
sfx2
smsFifo Size = 4

say Hello how are you?
well here we go
this is another string
sfx2
smsFifo Size = 8

say Hello how are you?
well here we go
this is another string
sfx2
smsFifo Size = 12

I could step through but I would like to understand where I'm going wrong with the For Each loop.

Here's the critical part of the code:
B4X:
For Each s As String In smsFifo
        Log(smsFifo.IndexOf(s) & " " & s) 
    Next

How is that doing matching rather than stepping through the entire list?

Confusing :)
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Suppose you have 4 elements, coffee, beer and then another coffee and another beer.
'For each' correctly loops through these four elements.
The problem is with indexof. Suppose we are at the third element of the loop, that is the second coffee. What is its indexOF in your list? Well, it is 0! Why? Because indexOf searches from the beginning of your list. Thus it finds coffee at its very first position. It will not then look further.
 
Upvote 0

IanMc

Well-Known Member
Licensed User
Longtime User
Well it looks like you're right :)

I put this in the Sub Globals:
B4X:
Dim count As Int

then my Sub fill_Click now looks like this:
B4X:
Sub fill_Click
   Dim theMagicWord As String = "bTi"
   Dim s As String = "       bti say Hello how are you?; well here we go; this is another string; sfx2"
   s = s.Trim
   If s.ToLowerCase.Trim.StartsWith(theMagicWord.ToLowerCase.Trim) Then ' its one for us otherwise let it go.
      Dim parts() As String 'Will also clear it right?
      parts = Regex.Split(";", s)
      parts(0) = parts(0).SubString(theMagicWord.Length)
      For Each j As String In parts
         count = count + 1
         j = j & " " & count 
         Log(j.Trim)
         smsFifo.Add(j) 'add it to the list baby! but don't clear it, add more if needed.
      Next
      Log("smsFifo Size = " & smsFifo.Size)
   Else
      Log("Nope, not one for us")
   End If
End Sub

And now it would seem that because each string is unique it gets its own element number .... even though before there were 12 elements..... still highly confusing, consider me confused :)

However this is now the output:
B4X:
List Print
0  say Hello how are you? 1
1  well here we go 2
2  this is another string 3
3  sfx2 4
4  say Hello how are you? 5
5  well here we go 6
6  this is another string 7
7  sfx2 8
8  say Hello how are you? 9
9  well here we go 10
10  this is another string 11
11  sfx2 12

It works for what I want it to do, just want to understand it better.
 
Upvote 0
Top