Author Topic: Seed parameter in the new _INSTRREV() statement.  (Read 9331 times)

0 Members and 1 Guest are viewing this topic.

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #15 on: April 08, 2019, 06:33:56 pm »
Also notice how it's useful to start at -1 so you don't have to bother with the length of the string. Again, as intended.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #16 on: April 08, 2019, 06:39:06 pm »
Ah well.  I never needed the command in the past.  As it is, I doubt I’ll ever use it in the future either.  All to their own.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #17 on: April 08, 2019, 10:10:32 pm »
Well, I tested it out with one of the forum index searches a few of us did a couple of months back. It worked fine for this particular application, but...

Code: QB64: [Select]
  1. s$ = ",bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,"
  2. PRINT "INSTR - Forward!"
  3.     seed& = INSTR(seed&, s$, ",dog,")
  4.     IF seed& = 0 THEN EXIT DO
  5.     x$ = MID$(s$, seed& + 1, LEN("dog"))
  6.     PRINT x$, seed&
  7.     seed& = seed& + LEN(",dog,")
  8. PRINT "_INSTRREV - Reverse!"
  9.     seed& = _INSTRREV(seed&, s$, ",dog,")
  10.     IF seed& = 0 THEN EXIT DO
  11.     x$ = MID$(s$, seed& + 1, LEN("dog"))
  12.     PRINT x$, seed&
  13.     seed& = seed& - LEN(",dog,")

If we add ,dog, as the first entry, it does that endless loop situation Steve brought up. That really needs to be changed.

Code: QB64: [Select]
  1. s$ = ",dog,bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,dog,"
  2. PRINT "INSTR - Forward!"
  3.     seed& = INSTR(seed&, s$, ",dog,")
  4.     IF seed& = 0 THEN EXIT DO
  5.     x$ = MID$(s$, seed& + 1, LEN("dog"))
  6.     PRINT x$, seed&
  7.     seed& = seed& + LEN(",dog,")
  8. PRINT "_INSTRREV - Reverse!"
  9.     seed& = _INSTRREV(seed&, s$, ",dog,")
  10.     IF seed& = 0 THEN EXIT DO
  11.     x$ = MID$(s$, seed& + 1, LEN("dog"))
  12.     PRINT x$, seed&: SLEEP
  13.     seed& = seed& - LEN(",dog,")
  14.  

I put a SLEEP statement in the _INSTRREV, so you can step through it rather than watch it repeat like crazy across the screen.

I added a ,dog, to the end of the string, too; however, this has no adverse effect. So only adding it at the beginning causes an issue of repeat looping.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #18 on: April 08, 2019, 10:12:45 pm »
The result of _INSTRREV will only ever be zero if the substring is *not* there. Please check the article, explanation and code I shared above.

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #19 on: April 08, 2019, 10:21:09 pm »
Also, check if the result is = 1 TO determine the end of search, as I showed in my snippet.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #20 on: April 08, 2019, 11:28:47 pm »
Or Steve, just because some $#$%^$$ in VBA made it that way, means we need to follow? QB compatible I get, but VBA compatible? Come on guys, that's bullscript in my ledger. Besides, VBA puts the damn seed as the third parameter.

Anyway, much like Steve I see having the function with an escape plan more efficient and elegant than what I had to quickly come up with to exit this QB64 VBA statement clone...

Code: QB64: [Select]
  1. strng$ = ",dog,bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,bill,cat,dog,dogfood,pete,steve,dog,"
  2. srch$ = ",dog,"
  3. PRINT "QB64's instrrev with Pete's escape method added..."
  4.     seed& = _INSTRREV(seed&, strng$, ",dog,")
  5.     IF seed& = 0 OR seed& > lastseed& AND lastseed& <> 0 THEN EXIT DO '  OR Needed to escape looping if string begins with search term.
  6.     x$ = MID$(strng$, seed& + 1, LEN("dog"))
  7.     PRINT x$, seed&
  8.     seed& = seed& - LEN(",dog,")
  9.     lastseed& = seed& ' Needed to escape looping if string begins with search term.
  10. PRINT "Pete's instrrev function with SMART escape...": seed& = 0
  11.     seed& = instrrev&(seed&, strng$, srch$)
  12.     IF seed& = 0 THEN EXIT DO
  13.     x$ = MID$(strng$, seed& + 1, LEN("dog"))
  14.     PRINT x$, seed&
  15.     seed& = LEN(strng$) - seed& + LEN(",dog,") - 1
  16.  
  17. FUNCTION instrrev& (seed&, strng$, srch$)
  18. b$ = SPACE$(LEN(strng$))
  19. srchx$ = SPACE$(LEN(srch$))
  20. FOR i& = LEN(srchx$) TO 1 STEP -1
  21.     j& = j& + 1
  22.     MID$(srchx$, j&, 1) = MID$(srch$, i&, 1)
  23. j& = 0
  24. FOR i& = LEN(b$) TO 1 STEP -1
  25.     j& = j& + 1
  26.     MID$(b$, j&, 1) = MID$(strng$, i&, 1)
  27. instrrev& = LEN(b$) + 1 - (INSTR(seed&, b$, srchx$) + LEN(srchx$) - 1)
  28. IF INSTR(seed&, b$, srchx$) = 0 THEN instrrev& = 0 ' It will now exit if asked.
  29.  

I will read that article tomorrow, sorry I could not get to it before coding this and a few other things.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #21 on: April 08, 2019, 11:47:21 pm »
This is like modulus for strings:
Code: QB64: [Select]
  1. _TITLE "INSTRREV test" 'B+ 2019-04-09 reminds me of modulus
  2.  
  3. s$ = " one two three four five six seven eight nine ten"
  4. lastFind = LEN(s$) + 1
  5. find = _INSTRREV(LEN(s$), s$, " ")
  6. n = 10
  7. WHILE find > 0
  8.     n = (n - 1) MOD 10
  9.     IF n < 0 THEN n = 9
  10.     PRINT n + 1,
  11.     PRINT MID$(s$, find + 1, lastFind - find - 1)
  12.     INPUT "OK... enter"; wate$
  13.     ' lastFind = find <<<don't need his line
  14.     IF find = 1 THEN lastFind = LEN(s$) + 1 ELSE lastFind = find
  15.     find = _INSTRREV(find - 1, s$, " ")
  16.  
« Last Edit: April 09, 2019, 12:30:51 am by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #22 on: April 09, 2019, 03:29:22 am »
And. since Fell wants to say that we need to be compatible with other languages with this one, perhaps he should take a moment to look at how .NET actually implements it: https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.strings.instrrev?redirectedfrom=MSDN&view=netframework-4.7.2#Microsoft_VisualBasic_Strings_InStrRev_System_String_System_String_System_Int32_Microsoft_VisualBasic_CompareMethod_

Let's take a close look at the RETURNS section:

If...... Start is greater than length of StringMatch   ....InStrRev returns.... 0.

Which is the exception I was trying to add into the command...

Also, let's take a close look at the ARGUMENT EXCEPTIONS:

ArgumentException:  Start = 0 or Start < -1.

So, as I mentioned in my previous post, you can have -1 be a shortcut to use the length of the whole search string, but 0 as a seed should return a value of 0.  It's too bad we're stuck with it being a feature the way it is now, rather than admitting it's a bug which would be rather simple to correct...

   
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline codeguy

  • Forum Regular
  • Posts: 174
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #23 on: April 09, 2019, 03:49:38 am »
Code: QB64: [Select]
  1. my$ = "tom jane fred lois dog cat mouse tom jerry mouse"
  2. t& = LEN(my$)
  3.     t& = InStringReverse&(t&, my$, "tom")
  4.     PRINT t&
  5.     IF t& > 0 THEN
  6.         t& = t& - LEN("tom")
  7.     ELSE
  8.         EXIT DO
  9.     END IF
  10. LOOP WHILE t& > 0
  11.  
  12. FUNCTION InStringReverse& (start&, x$, f$)
  13.     ps& = start& - LEN(f$) + 1
  14.     IF ps& > 0 THEN
  15.         DO
  16.             IF ps& > 0 THEN
  17.                 IF MID$(x$, ps&, LEN(f$)) = f$ THEN
  18.                     EXIT DO
  19.                 ELSE
  20.                     ps& = ps& - 1
  21.                 END IF
  22.             ELSE
  23.                 EXIT DO
  24.             END IF
  25.         LOOP
  26.     END IF
  27.     InStringReverse& = ps&
  28.  

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #24 on: April 09, 2019, 04:08:57 am »
Code: QB64: [Select]
  1. my$ = "tom jane fred lois dog cat mouse tom jerry mouse"
  2. t& = LEN(my$)
  3.     t& = InStringReverse&(t&, my$, "tom")
  4.     PRINT t&
  5.     IF t& > 0 THEN
  6.         t& = t& - LEN("tom")
  7.     ELSE
  8.         EXIT DO
  9.     END IF
  10. LOOP WHILE t& > 0
  11.  
  12. FUNCTION InStringReverse& (start&, x$, f$)
  13.     ps& = start& - LEN(f$) + 1
  14.     IF ps& > 0 THEN
  15.         DO
  16.             IF ps& > 0 THEN
  17.                 IF MID$(x$, ps&, LEN(f$)) = f$ THEN
  18.                     EXIT DO
  19.                 ELSE
  20.                     ps& = ps& - 1
  21.                 END IF
  22.             ELSE
  23.                 EXIT DO
  24.             END IF
  25.         LOOP
  26.     END IF
  27.     InStringReverse& = ps&
  28.  

That's basically how it should behave, codeguy, with one minor change:

Code: QB64: [Select]
  1. my$ = "tom jane fred lois dog cat mouse tom jerry mouse"
  2. t& = -1
  3.     t& = InStringReverse&(t&, my$, "tom")
  4.     PRINT t&
  5.     IF t& > 0 THEN
  6.         t& = t& - LEN("tom")
  7.     ELSE
  8.         EXIT DO
  9.     END IF
  10. LOOP WHILE t& > 0
  11.  
  12. FUNCTION InStringReverse& (start&, x$, f$)
  13.     IF start& = -1 THEN start& = LEN(x$)
  14.     ps& = start& - LEN(f$) + 1
  15.     IF ps& > 0 THEN
  16.         DO
  17.             IF ps& > 0 THEN
  18.                 IF MID$(x$, ps&, LEN(f$)) = f$ THEN
  19.                     EXIT DO
  20.                 ELSE
  21.                     ps& = ps& - 1
  22.                 END IF
  23.             ELSE
  24.                 EXIT DO
  25.             END IF
  26.         LOOP
  27.     END IF
  28.     InStringReverse& = ps&
  29.  

IF start& = -1 THEN start& = LEN(x$) is a shortcut so you don't have to manually type LEN(my$) to start a search at the end of the string.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #25 on: April 09, 2019, 05:53:55 am »
Hi guys
fine to learn the existence of this function from you , among the tons of other news in QB64.

before to say a silly thing I try to resume that I have understood from your talking about the right value returned by _INSTRREV when there is a problem with parameters...
1. _INSTRREV is not the simmetrical opposite of INSTR

syntax
_INSTRREV (WheretoSearch$, WhattoSearch$, UntilLastRightCharacterConsidered%,CompareMethod%)
                              ^                          ^                         ^                                                          ^
                              |                            |                          |                                                            |   Who is it?
 string in which we search                  |                          |                                                                  is there In QB64 version of the function?
                                      string to search                        |                                                           
                                                                   Start is a BAD name for this parameter because in this function it shows the last right character of the string to consider in the searching task, but it is right the first character used because the searching comes from right to left (in this sense we can call it START)  but we always read the string from left to right and count the position from the left to right!

To be simmetrical (Reverse INSTR) it would count from the start position ie from the last right character considered going to the left. But this is not the issue.

So _INSTRREV  searches a string1 into a string2 starting from the right side of the string2 less the start position, going to left . The result is the position of string1 counting from the left side of string2.
If start is omitted it is -1 by default and the seaching starts from the last right character of string2.

Here my questions
1. the parameter Compare% is implemented in QB64 _INSTRREV?
2. What have I missed to understand only half of the example that is here https://www.techonthenet.com/excel/formulas/instrrev.php  ?
3. what is the difference between Start = 0, Start = null and Start omitted in QB64?
Quote
If start is null, the INSTRREV function will return #Error.
4. why INSTRREV must return 0 if Start is greater StringMatch ?
Quote
StringMatch
String
Required. String expression being searched for.

Start
Int32
Optional. Numeric expression setting the one-based starting position for each search, starting from the left side of the string. If Start is omitted then -1 is used, meaning the search begins at the last character position. Search then proceeds from right to left.
« Last Edit: April 09, 2019, 05:56:09 am by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #26 on: April 09, 2019, 06:00:07 am »
this code confirms the result of this page https://www.techonthenet.com/excel/formulas/instrrev.php
Code: QB64: [Select]
  1. string1 = "alphabet"
  2. string2 = "a"
  3.  
  4. PRINT _INSTRREV(string1, string2)
  5. FOR a = 1 TO 9 STEP 1
  6.  
  7.     PRINT _INSTRREV(a, string1, string2)

Sorry for previous syntax I have written looking at syntax showed here https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.strings.instrrev?redirectedfrom=MSDN&view=netframework-4.7.2#Microsoft_VisualBasic_Strings_InStrRev_System_String_System_String_System_Int32_Microsoft_VisualBasic_CompareMethod_
and here
https://www.techonthenet.com/excel/formulas/instrrev.php

then try to code to use _INSTRREV i have learned from your examples posted that in QB64 synthax comes first Start parameter and then the StringInWhichSearch and following StringToSearch.
« Last Edit: April 10, 2019, 09:22:53 am by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #27 on: April 09, 2019, 06:08:50 am »
Off-topic discussion that was taking place in this thread has been moved to https://www.qb64.org/forum/index.php?topic=1233.msg104360#msg104360

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #28 on: April 09, 2019, 06:11:13 am »
Quote
Here my questions
1. the parameter Compare% is implemented in QB64 _INSTRREV?
2. What have I missed to understand only half of the example that is here https://www.techonthenet.com/excel/formulas/instrrev.php  ?
3. what is the difference between Start = 0, Start = null and Start omitted in QB64?
Quote
If start is null, the INSTRREV function will return #Error.
4. why INSTRREV must return 0 if Start is greater StringMatch ?

1.  Nope.  We don’t offer the binary compare method; it wasn’t implemented.

2.  I dunno what you missed.  ;)

3.  If start is omitted, it defaults to the length of the string to be searched.  QB64 does the same, currently, if start = 0, though .NET tosses an error as they use 1 as the terminating value. I don’t think you can pass start a nul in QB64.

4.  I actually think that’s a typo on Microsoft’s page (unless it does so to keep the user from trying to read beyond the length of memory allocated for the string.)  i’m thinking it should read “if start is les than length of StringMatch”.   After all, you can’t find a 7 letter search string in a 3 letter word.  If your start = 3 and len(searchstring) > 3, it should always return 0.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #29 on: April 09, 2019, 08:43:06 am »
Hi Steve
thanks for your time and energy

your answers are clear and logic and I have miss my mind :-), I think that my bug knownledge is about how Start works into the function
Quote
_INSTRREV (Start%, WheretoSearch$, WhattoSearch$ )
if WheretoSearch$ Is "  a l p h a b e t " and Start% = 1

question:
A)
  a l p h a b e t
                     ^
                      |
              is  Start  here if it is equal 1 ?

B)
                     a l p h a b e t
                     ^
                      |
        is  Start  here if it is equal 1 ?


C) Start moves toward left or right?

Thanks
Programming isn't difficult, only it's  consuming time and coffee