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

0 Members and 1 Guest are viewing this topic.

Offline codeguy

  • Forum Regular
  • Posts: 174
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #45 on: April 09, 2019, 08:27:11 pm »
I am going to lightly campaign for this function to mostly mirror INSTR() in returning a value of 0...lengthofstring-lengthofsearchstring+1 in the next STABLE release and leave it as is until then. This behavior would keep it in line with the predictable INSTR(), which never returns a negative result and doesn't conflict with the construct people including me use with INSTR (ie: WHILE INSTR(startpos&, some$, find$). Perhaps starting with 0 as a seed value could indicate the WHOLE string is to be searched and if it returns a 0, the string to find is not contained in the string to be searched, the very same as INSTR(). JM2C (just my 2 cents). I don't think there's any need to get in arguments, just agree on a position SOMEWHERE between that won't completely wreck things.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #46 on: April 09, 2019, 10:11:26 pm »
I have never used _INSTR() or INSTREV() before, but if this is an issue of consistency, I would highly recommend going for consistency in the functions, even if it means some current programs will break as a result.

After a decade of using PHP, I can say by far the worst part of it for me is the entirely inconsistent functions!  Some function names have the modifier at the end, some at the start.  Functions that are mirrors of each other have parameters in the opposite order, etc.  It's a giant ugly mess, and makes it far harder to learn the programming language than it needs to be.  If you have "foo_on()" you should have "foo_off()" not "disable_foo()".  Programmers in general have a focus to details and consistency, as is needed to be good at programming.  Functions that don't operate as expected, or are not named as expected, are a burden.  It takes you out of programming logic, instead forcing you to focus on remembering the inconsistencies.


The descriptions read:

 -and-


These don't behave the same?

Because their descriptions say they do, and the function name with REV at the end indicates it is the same but reversed.

They don’t behave the same, currently.

This is the current INSTR:
Code: QB64: [Select]
  1.     seed = _INSTR(seed + 1, “AAAA”, “A”)
  2.     PRINT seed
  3. LOOP UNTIL seed = 0
  4.  

And,this is currently how you’d do that with _INSTRREV:
Code: QB64: [Select]
  1. seed = LEN(“AAAA”) + 1
  2.     seed = _INSTRREV(seed - 1, “AAAA”, “A”)
  3.     PRINT seed
  4. LOOP UNTIL seed = 0 OR seed = 1

Notice how INSTR terminates with a 0?  That basically means, “No more “A” in the string we’re searching.”

_INSTRREV requires you to check for both 0 and 1 values.  0 says, “Nope.  No more “A” found in the string”, but you ALSO have to check for that 1, so you know you’re at the end of the string to search

The change I propose is rather simple, and shouldn’t break any existing code:  Fix _INSTRREV so that it stops checking at the 0th byte of a string, rather than starting back over from the right side again.  All we need to know is “0 means no more search strings found”.   WTH do we need to complicate the process with multiple checks for “am I at the last position in the string”, and “is there no more search strings found”?

_INSTRREV could easily match INSTR’s functionality with a single line change in libqb.cpp.  Unfortunately, the glitch wasn’t found 10 months ago in the beta versions, so it’s now officially a feature and not a bug.

It’s sad to say, but it seems the choice is to either get used to learning the inconsistencies between the two commands, or patch the issue yourself and have code you share with the patched version be incompatible with the general forum community.
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 #47 on: April 09, 2019, 11:45:54 pm »
Here's a good example why I wish it was mirrored with seeding in the first place. Let's say you have a giant list of records, a million plus, delimited by "|" 4 spaces apart, and you want to find the 3rd record from the end of the data file. Well you would think with a reverse INSTR() keyword, you could just ask for the function to return the 3rd record from the end (12-characters from the right) but a seed of 12 in this non-mirror reverse instr() function will just chop off the string after the 12th character from the LEFT, and get the last record in that chopped string. That will be the 3rd record, as per this example, not the 3rd record from the end. To get that record, you'd have to know how many records in total exists, subtract 3 * 4, and use that as the seed. Sure, it's doable, but to me it seems counterintuitive.

OK, so we can work with seeding from left to right in INSTR() and _INSTRREV(), but it does take some alteration, because one is searching forward while the other is searching from behind. Notice I had to alter the seedr% to the seedf% variable to obtain equal results in the following code example.

Code: QB64: [Select]
  1. WIDTH 80, 43
  2.     s$ = "r1 |r2 |r3 |r4 |r5 |r6 |r7 |r8 |r9 |r10|r11|r12"
  3.     s$ = "|" + s$ + "|" ' Enclose.
  4.     PRINT "         1111111111222222222233333333334444444444"
  5.     PRINT "1234567890123456789012345678901234567890123456789"
  6.     PRINT s$: PRINT
  7.     srch$ = "|": interval% = 4
  8.     INPUT "Get record 1-12"; rec%: PRINT
  9.     seedf% = rec% * interval% - interval% + 1
  10.     seedr% = rec% * interval%
  11.     PRINT MID$(s$, INSTR(seedf%, s$, "|") + 1, interval% - 1); " First record"; seedf%; "spaces in from the left. INSTR() ="; INSTR(seedf%, s$, "|")
  12.     PRINT MID$(s$, _INSTRREV(seedr%, s$, "|") + 1, interval% - 1); " Last record within"; seedr%; "spaces from the left. INSTRREV() ="; _INSTRREV(seedr%, s$, "|")
  13.     PRINT
  14.  

Here is a simple comparison of INSTR() and INSTRREV() with a seeded loop.

Code: QB64: [Select]
  1. s$ = "@#a012a345a67a89"
  2. COLOR 7, 0: PRINT "1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16"
  3. COLOR 14, 0: PRINT "@  #  a  0  1  2  a  3  4  5  a  6  7  a  8  9": COLOR 7, 0
  4. PRINT "INSTR()     _INSTRREV()"
  5. FOR i = 1 TO LEN(s$)
  6.     PRINT i; MID$(s$, INSTR(i, s$, "a"), 2), i; MID$(s$, _INSTRREV(i, s$, "a"), 2)

I've used INSTR() over the years probably more than anyone else on this forum. I've always thought it would be great to have a mirror reverse function, but this just isn't quite it. I'm still trying to figure any advantages vs disadvantages with seeding left to right vs right to left, but the one I really cannot find a reason to support is that looping "feature" we've pointed out some message posts back. I feel it needs a valid reason(s) to exist in terms of effecting a desired coding result. Are there any?

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

Offline codeguy

  • Forum Regular
  • Posts: 174
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #48 on: April 10, 2019, 01:30:35 am »
For not-too-large strings, my String reversed method and the calculation used to produce the result in the actual string works perfectly with INSTR() as-is. I tend to avoid novelties like _INTRREV() because they do not mirror the way INSTR() works as I'd expect and apparently you too. Mine is correct, although it may not be the fastest algorithm on earth to achieve the end goal. I have used INSTR() perhaps second-most of all the members here. Mine is a tried and proven way to achieve exactly what you want to do.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #49 on: April 10, 2019, 01:52:07 am »
As much as I respect you, Pete, I'll tell you what I've told Steve all day: We have JUST released a new version of QB64 with a feature that's been added 10 months back, overtly talked about in this forum. This not the time to lobby for a change.

The way _INSTRREV works is the way it was designed to work 10 months back. Back then all sorts of discussion and concession would have been easier.

Right now what we have is a stable release being advertised everywhere I can and which works as indicated in the wiki, link in my previous post.

Code: QB64: [Select]
  1. I still lobby for make _INSTRREV() work more like my function
Adjusting your expectations here means accepting that a function that *didn't exist before* now exists and works as it's been explained. And you now have written yourself a nice function for your own use that does exactly what you expect it to. Just like codeguy has been doing for a while now too in this thread.

People will read the wiki and learn how the new feature works. And they'll either use it or not. We have features galore and not everyone uses all of them.

Can we please celebrate a new release and cut back on the clippiness?

I appreciate that, and I appreciate all the work that goes into making a new release. This reminds me a bit of the postman who delivered a letter through the proverbial snow, rain, heat and gloom of night and the recipient replied. Hey look ascii-hole, you creased the bottom left corner! Actually, I have a more real life similar experience, of when I would bust my but on my office software, reach a finished version, and my wife would say something to the effect of, "Hey dear, you know would would be great..." followed by a laundry list of functions that would only take another couple of minutes, and by minutes, I mean months, to create. Sigh.... A few days after reentry, I'd cool down and since her ideas were generally good ones, get busy and code some more. So to me, this is all a process.

Anyway, we do have a lot to celebrate and to be thankful for. While others have had their coding rugs ripped out from underneath them, this community has managed to manufacture its own stable foundation and, unlike FB, it's still on sound footing. Sure, member tempers flare on occasion, but that's mostly because people care a lot about the project. I'll take that over apathy, any day.

I have used INSTR() a lot. _INSTRREV() will be great for getting the file name, dotcom name, etc., off a long file path/file name string. That by itself is something to crow about. I'm not sure why you feel removing the looping "feature" would not make it better when it comes to use with seeds. Maybe I'm missing something but if so, what possible good use does keeping that serve? I know you wre working on this for the past 10 months, but I only found that out about a week ago. No one sent me a memo, or on my end, I guess I hadn't paid too much attention to the development thread. So, it's new to me.

You know on the N54 Forum, I used to refer to Steve as my evil twin. Funny thing, I used to tell my wife, nearly 30 years ago, when I pulled some stunt she disapproved of, "Honey, it wasn't me, it was my evil twin, Steve!" That got me out of the dog house every time. Imagine my surprise when that figment of my imagination came to life! I just wish I hadn't built him up so much, because he really gives me a run for my money at times. I'd miss him a bunch if he didn't come around anymore. I actually offered him the QB Forum at one point, but he had other pressing matters, something about a lemonade stand, but I digress. Anyway, I hope the two of you can patch things up between each other as well as you can patch up code in the project, and we can all move forward, together.

Oh, and it's Clipishness, not Clippiness. ;)

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

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #50 on: April 10, 2019, 09:40:43 am »
Hi
Thanks

 @Steve to dissolve my shadow in knowledge... before I have thought that the start, being in reverse, was at the right of string and it move itself toward left!

@Fellippe
for quick wiki of _INSTRREV

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

Offline Raven_Singularity

  • Forum Regular
  • Posts: 158
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #51 on: April 10, 2019, 12:48:32 pm »
Sure, member tempers flare on occasion, but that's mostly because people care a lot about the project. I'll take that over apathy, any day.

Hear, hear!

Apathy destroys good software projects every day.


To be clear, I am not trying to belittle all the programming efforts of the QB64 developers.  I have being programming for 32 years, so I know how much work goes into designing, programming, and debugging an app.  I respect that this function was discussed in development 10 months ago, and made its way into the stable branch of QB64.  That said, I still think it would be a better idea to change these functions to be consistent with each other, for the next major stable release, even if it affects some peoples current QB64 code.
« Last Edit: April 10, 2019, 12:50:37 pm by Raven_Singularity »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Seed parameter in the new _INSTRREV() statement.
« Reply #52 on: April 10, 2019, 03:40:11 pm »
I didn't want to leave this thread without posting an example of what I mean by a mirror INSTR() function. Basically such a function would look for the sub-string of the string from right to left (backwards searching) but the seed would also be backwards searching. So a seed of 2 would mean, look in 2 characters from the right, and then find the last sub-string occurrence from that point. Here is an example of such a mirror function:

Code: QB64: [Select]
  1. strng$ = "rec-1 ,rec-2 ,rec-3 ,rec-4 ,rec-5 ,"
  2. srch$ = ","
  3. INPUT "Go in this many characters from the right and search backwards from there: "; seed&
  4. rec& = instrrev&(seed&, strng$, srch$)
  5. x$ = MID$(strng$, rec& - 6, 6)
  6. PRINT "Found: "; RTRIM$(x$); " within"; seed&; "spaces from the right at position:"; rec&
  7.  
  8. FUNCTION instrrev& (seed&, strng$, srch$)
  9. FOR instrrev& = LEN(strng$) + 1 - seed& TO 1 STEP -1
  10.     IF MID$(strng$, instrrev&, LEN(srch$)) = srch$ THEN EXIT FOR
  11. IF srch$ = "" OR instrrev& < 0 THEN instrrev& = 0
  12.  
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/