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

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Seed parameter in the new _INSTRREV() statement.
« on: April 08, 2019, 03:25:17 pm »
I don't think the first parameter of the new _INSTRREV() works. That would be the seed variable.

Code: QB64: [Select]
  1. strng$ = "*,@,h,&,h,a,b,c,d,e,f,g,h,1,2,h"
  2. srch$ = "h"
  3. seed& = 2
  4. PRINT instrrev&(seed&, strng$, srch$) ' My function returns 25, the position of the next h, from the end, less 2-characters in.
  5. PRINT _INSTRREV(2, strng$, "h") 'This should not be a zero.
  6.  
  7. FUNCTION instrrev& (seed&, strng$, srch$)6
  8.     b$ = SPACE$(LEN(strng$))
  9.     FOR i& = LEN(b$) TO 1 STEP -1
  10.         j& = j& + 1
  11.         MID$(b$, j&, 1) = MID$(strng$, i&, 1)
  12.     NEXT
  13.     instrrev& = LEN(b$) - INSTR(seed&, b$, srch$) + 1

So if you don't seed it, and just use, PRINT _INSTRREV(strng$, "h"), it will return 31, which is the location of the h at the end, but if you seed it to, PRINT _INSTRREV(2, strng$, "h"), it just returns a zero. In other words, if it is going 2-characters in from the end, it should ignore the h on the end, which it does, but it should find the next h from the end, which it doesn't.

Pete

« Last Edit: April 08, 2019, 03:59:39 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: I think the seed parameter in the new _INSTRREV() doesn't work.
« Reply #1 on: April 08, 2019, 03:45:06 pm »
Hi. I think the number two is the position from the beginning of the string and then it would be fine.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: I think the seed parameter in the new _INSTRREV() doesn't work.
« Reply #2 on: April 08, 2019, 03:55:35 pm »
When you enter position 9, it search from the ninth position toward the beginning and returns 8, and that's ok.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: I think the seed parameter in the new _INSTRREV() doesn't work.
« Reply #3 on: April 08, 2019, 03:55:43 pm »
Hi. I think the number two is the position from the beginning of the string and then it would be fine.

You're right. I tried, PRINT _INSTRREV(7, strng$, "h"), and it displayed position 5, the position of the last h, 7 or less characters in. It just seems weird to use it that way.

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

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #4 on: April 08, 2019, 04:15:23 pm »
I modified the message title. Since this is not in the wiki, maybe others will reference this topic, if needed.

Anyway, I just have to change my mirror image mindset and just make the seed variable the length of the string, to start, and progressively subtract. No biggie.

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 #5 on: April 08, 2019, 04:22:49 pm »
Another example:
Code: QB64: [Select]
  1. _TITLE "INSTRREV test" 'B+ 2019-04-08
  2.  
  3. s$ = "one two three four five six seven eight nine ten"
  4. find = _INSTRREV(LEN(s$), s$, " ")
  5. WHILE find > 0
  6.     'PRINT LEFT$(s$, find - 1)
  7.     PRINT MID$(s$, find + 1)
  8.     find = _INSTRREV(find - 1, s$, " ")
  9.  

EDIT: liked the slippery slope version better
« Last Edit: April 08, 2019, 04:26:41 pm 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 #6 on: April 08, 2019, 04:29:42 pm »
Something here seems off to me as well.

Here's a standard loop where we'd see where the "1" appears in "1111":

Code: QB64: [Select]
  1.     seed = INSTR(seed + 1, "1111", "1")
  2.     PRINT seed
  3. LOOP UNTIL seed = 0

Now, if we want to do the same with _INSTRREV, we end up with a problem:

Code: QB64: [Select]
  1. seed = LEN("1111") + 1
  2.     seed = _INSTRREV(seed - 1, "1111", "1")
  3.     PRINT seed
  4.     SLEEP
  5. LOOP UNTIL seed = 0

With _INSTRREV, the seed is currently the number from the left, so when we do _INSTRREV(3, "abcdef", whatever$), what we're looking for is where whatever$ appears in "abc".  With _INSTRREV(2, "abcdef", whatever$), what we're looking for is where whatever$ appears in "ab".

But when the seed becomes 0, what we look for is where whatever$ appears in "abcdef"...

If seed represents basically working with LEFT$(search$,seed), then a seed of 0 should always return "" instead of the search$.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #7 on: April 08, 2019, 04:32:36 pm »
Another example:
Code: QB64: [Select]
  1. _TITLE "INSTRREV test" 'B+ 2019-04-08
  2.  
  3. s$ = "one two three four five six seven eight nine ten"
  4. find = _INSTRREV(LEN(s$), s$, " ")
  5. WHILE find > 0
  6.     'PRINT LEFT$(s$, find - 1)
  7.     PRINT MID$(s$, find + 1)
  8.     find = _INSTRREV(find - 1, s$, " ")
  9.  

EDIT: liked the slippery slope version better

To also illustrate the isue, let's use Bplus's code with an extra space at the front of the string:

Code: QB64: [Select]
  1. _TITLE "INSTRREV test" 'B+ 2019-04-08
  2.  
  3. s$ = " one two three four five six seven eight nine ten"
  4. find = _INSTRREV(LEN(s$), s$, " ")
  5. WHILE find > 0
  6.     'PRINT LEFT$(s$, find - 1)
  7.     PRINT MID$(s$, find + 1), find
  8.     find = _INSTRREV(find - 1, s$, " ")
  9.  
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #8 on: April 08, 2019, 04:37:57 pm »
Oh my poor befuddled code!
Code: QB64: [Select]
  1. _TITLE "INSTRREV test" 'B+ 2019-04-08
  2.  
  3. 'big problem if the s$ starts with a space!!! as pointed out by Steve.
  4.  
  5. s$ = "   one two three four five six seven eight nine ten"
  6. find = _INSTRREV(LEN(s$), s$, " ")
  7. WHILE find > 0
  8.     'PRINT LEFT$(s$, find - 1)
  9.     PRINT MID$(s$, find + 1), find
  10.     IF find > 1 THEN find = _INSTRREV(find - 1, s$, " ") ELSE EXIT WHILE
  11.  
« Last Edit: April 08, 2019, 04:48:41 pm 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 #9 on: April 08, 2019, 05:06:13 pm »
Fix to this issue is rather simple:

In libqb.cpp, go in and find the func_instrrev.  Change the following:
Code: QB64: [Select]
  1.     if (start<1){
  2.         start=str->len-substr->len+1;
  3.     }

To:

Code: QB64: [Select]
  1. if (start<substr->len) return 0;

Is the seed is less than 1, we don't want to compare against the whole of the string.  We simply want to say there's no substring inside the searchstring.



Unless there's some odd and unfathomable (to me, at the moment, at least) reason for it to behave as it currently is, I can easily push the changes into the repo and correct this minor issue, if you guys want.
« Last Edit: April 08, 2019, 05:07:51 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #10 on: April 08, 2019, 05:12:44 pm »
I'd like you gentlemen to please adjust your expectations. Especially considering that the wiki article is still being written, as pointed out above.

With the exception of the last case stated in the list contained in https://www.techonthenet.com/excel/formulas/instrrev.php (under the header "Example (as VBA Function)"), the behavior of the new function is expected to be as described in the link I now share. And it is.

Fellippe.
« Last Edit: April 08, 2019, 05:17:43 pm by FellippeHeitor »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #11 on: April 08, 2019, 05:23:23 pm »
I'd like you gentlemen to please adjust your expectations. Especially considering that the wiki article is still being written, as pointed out above.

With the exception of the last case stated in the list contained in https://www.techonthenet.com/excel/formulas/instrrev.php (under the header "Example (as VBA Function)"), the behavior of the new function is expected to work as described in the link I now share.

Fellippe.

I honestly think the change I just posted before you, is the one you're wanting so that it behaves as indicated.

What you currently have is:

Code: QB64: [Select]
  1.    if (start<1){
  2.         start=str->len-substr->len+1;
  3.     }

Which basically translates down to:

IF start < 1 THEN
  start = LEN(mainstring$) - LEN(searchstring$) + 1
END IF

Let's say I have a search string of "1234567890abc".

If I'm looking for "abc" in the -3rd position of that string, I should either:
1) Get an error as there is no -3rd position of that string.
2) Get a return value of 0, as there is no -3rd position of that string.

I certainly don't think I should get a value of 11 by searching left from the -3rd position... 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #12 on: April 08, 2019, 05:31:09 pm »
In the link I just shared there's a use for a negative value (-1 specifically, but I didn't bother not generalize). I'll let you have a look first.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #13 on: April 08, 2019, 05:35:00 pm »
In the link I just shared there's a use for a negative value (-1 specifically, but I didn't bother not generalize). I'll let you have a look first.

I saw it.  I just don't think you really want it.

As the command exists currently, fix this so that it properly terminates as intended for us:
Code: QB64: [Select]
  1. seed = LEN("1111") + 1
  2.     seed = _INSTRREV(seed - 1, "1111", "1")
  3.     PRINT seed
  4.     SLEEP
  5. LOOP UNTIL seed = 0

With a seed of 0, or less, we need to terminate search; not go back to the beginning of the string and start over again.



To compare behavior, take a run of this little set of code:

Code: QB64: [Select]
  1. PRINT INSTR(11, "1234567890", "1")
  2. PRINT _INSTRREV(-1, "1234567890", "1")

There's no "1" from the 11th position of our "1234567890" to the right of it.  The result is 0.
Yet, we found a "1" somewhere to the left of our -1st position of that string?

Shouldn't both of these functions return the same value, if a substring only exists once inside the searchstring?
« Last Edit: April 08, 2019, 05:42:37 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #14 on: April 08, 2019, 06:32:12 pm »
I understand that the name may give the idea these functions should be mere mirrors of each other and although at some points they are, the mindset here is different. With that in mind, I repeat: it's a matter of adjusting your expectations. The function behaves as intended.

Code: QB64: [Select]
  1.     seed = _INSTRREV(seed - 1, "1111", "1")
  2.     PRINT seed
  3. LOOP UNTIL seed = 0 OR seed = 1
  4. IF seed = 0 THEN PRINT "substring not found"
  5. IF seed = 1 THEN PRINT "substring found at beginning of main string; search interrupted"
  6.