Recent

Author Topic: Determine if a char  (Read 9509 times)

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Determine if a char
« on: December 12, 2018, 05:55:25 am »
I can't get this code segment to work.

TFRecord is defined as :
TFRecord : String;

Code: Pascal  [Select][+][-]
  1.  for Idx := 0 to 4 do begin
  2.     Character := TFRecord[Idx];
  3.     if char <> 'A' .. 'Z'  then begin Valid := False; end;
  4.    end;      
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Determine if a char
« Reply #1 on: December 12, 2018, 05:57:53 am »
It should be:

Code: Pascal  [Select][+][-]
  1. Valid := True;
  2. for Idx := 1 to Length(TFRecord) do
  3. begin
  4.   Character := TFRecord[Idx];
  5.   if (Character < 'A') or (Character > 'Z') then Valid := False;
  6. end;

You have 2 serious mistakes and 2 potential issues:
- Your Idx start from 0, it is wrong.
- You compare the 'char' with 'A'..'Z', it is wrong.
- You should not hardcode the value 4.
- You maybe forgot to initial the variable Valid.

Note:
Programmers usually name the looping variable i. You don't have to but if you want to follow the common standard you should rename the variable Idx to i.

---edit---
Fix some typing mistakes.
« Last Edit: December 12, 2018, 06:37:47 am by Handoko »

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Determine if a char
« Reply #2 on: December 12, 2018, 06:02:15 am »
It giving me the following error on:
  if Character <> 'A' .. 'Z'  then begin Valid := False; end;

line unit1.pas(112,20) Fatal: Syntax error, "THEN" expected but ".." found
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Determine if a char
« Reply #3 on: December 12, 2018, 06:04:24 am »
It giving me the following error on:
  if Character <> 'A' .. 'Z'  then begin Valid := False; end;

line unit1.pas(112,20) Fatal: Syntax error, "THEN" expected but ".." found
if not (character in ['A' .. 'Z']) then Valid := false;

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Determine if a char
« Reply #4 on: December 12, 2018, 06:12:31 am »
Yeah, I wrote it too fast.  :-[
correct the post and I'll delete my last two posts too.

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Determine if a char
« Reply #5 on: December 12, 2018, 06:14:13 am »
Code: Pascal  [Select][+][-]
  1. function TForm1.CheckCharacters(aRec : String) : Boolean;
  2.  Var
  3.   TFRecord : String = '';
  4.   Character : Char;
  5.   Idx : Integer = 0;
  6.   Valid : Boolean = True;
  7.  begin
  8.   TFRecord := aRec;
  9.     for Idx := 1 to Length(TFRecord) do begin
  10.      Character := TFRecord[Idx];
  11.      if Not (Character in  ['A' .. 'Z'])  then begin Valid := False; end;
  12.     end;
  13.      Result := Valid;
  14.  end;                                                  

This compiles but I haven't run it yet.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Determine if a char
« Reply #6 on: December 12, 2018, 06:16:16 am »
Code: Pascal  [Select][+][-]
  1. function TForm1.CheckCharacters(aRec : String) : Boolean;
  2.  Var
  3.   TFRecord : String = '';
  4.   Character : Char;
  5.   Idx : Integer = 0;
  6.   Valid : Boolean = True;
  7.  begin
  8.   TFRecord := aRec;
  9.     for Idx := 1 to Length(TFRecord) do begin
  10.      Character := TFRecord[Idx];
  11.      if Not (Character in  ['A' .. 'Z'])  then begin Valid := False; end;
  12.     end;
  13.      Result := Valid;
  14.  end;                                                  

This compiles but I haven't run it yet.
looks good

JLWest

  • Hero Member
  • *****
  • Posts: 1293
Re: Determine if a char
« Reply #7 on: December 12, 2018, 06:20:46 am »
Thanks all; I think it works.

Tested on a small record set.

So I'll turn it on with the 27,000 record set and watch one of the NFL games I taped.

FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

HeavyUser

  • Sr. Member
  • ****
  • Posts: 397
Re: Determine if a char
« Reply #8 on: December 12, 2018, 06:30:36 am »
Thanks all; I think it works.

Tested on a small record set.

So I'll turn it on with the 27,000 record set and watch one of the NFL games I taped.
now that you have a working version I'd like to propose a small change
Code: Pascal  [Select][+][-]
  1. function TForm1.CheckCharacters(aRec : String) : Boolean;
  2.  Var
  3.   TFRecord : String = '';
  4.   Character : Char;
  5.   Idx : Integer = 0;
  6.   Valid : Boolean = True;
  7.  begin
  8.   TFRecord := aRec;
  9.     for Idx := 1 to Length(TFRecord) do begin
  10.      Character := TFRecord[Idx];
  11.      if Not (Character in  ['A' .. 'Z'])  then begin Valid := False; Break; end;
  12.     end;
  13.      Result := Valid;
  14.  end;                                                  
this will speed things up a bit on invalid strings but it will not have any effect on correct strings which makes it a very very small enhancement overall.

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Determine if a char
« Reply #9 on: December 12, 2018, 08:35:04 am »
Here is another version of your function after a weight loss program...

Code: Pascal  [Select][+][-]
  1. function CheckCharacters(aRec : string) : boolean;
  2. var
  3.   idx : integer;
  4.  
  5. begin
  6.   result := false;
  7.  
  8.   for idx := 1 to length(aRec) do
  9.   begin
  10.     if not (aRec[idx] in ['A'..'Z']) then exit;
  11.   end;
  12.  
  13.   result := true;
  14. end;
  15.  
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Determine if a char
« Reply #10 on: December 12, 2018, 12:16:55 pm »
@440bx based on your code, a little bit more:
Code: Pascal  [Select][+][-]
  1. function CheckCharacters(aRec : string) : boolean;
  2. var
  3.   idx : integer;
  4. begin
  5.   for idx := 1 to length(aRec) do
  6.     if not (aRec[idx] in ['A'..'Z']) then exit(false);
  7.  
  8.   result := true;
  9. end;

or:
Code: Pascal  [Select][+][-]
  1. function CheckCharacters(aRec : string) : boolean;
  2. var
  3.   c : char;
  4. begin
  5.   for c in aRec do
  6.     if not (c in ['A'..'Z']) then exit(false);
  7.  
  8.   result := true;
  9. end;

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Determine if a char
« Reply #11 on: December 12, 2018, 02:16:57 pm »
Wow, I did not know you could do 

Code: Pascal  [Select][+][-]
  1. for c in aRec do

Really useful.

But I wonder why this thread moved away from Handoko's

Code: Pascal  [Select][+][-]
  1. if (Character < 'A') or (Character > 'Z') then

Model. I would have thought it would be faster ?  By testing against the set of 'A'..'Z' we'd do 26 comparisons, Handoko's model only does two ?

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Determine if a char
« Reply #12 on: December 12, 2018, 02:40:47 pm »
But I wonder why this thread moved away from Handoko's
Code: Pascal  [Select][+][-]
  1. if (Character < 'A') or (Character > 'Z') then
Model. I would have thought it would be faster ?  By testing against the set of 'A'..'Z' we'd do 26 comparisons, Handoko's model only does two ?

Operations on sets are (normally) compiled into a single logical comparison so they are quicker; p.e. in this case the comparison is somthing like the pseudo:
Code: ASM  [Select][+][-]
  1. AND bit(char), qword(SetAZ)
  2. JZ Next
  3. . . .
Remember that the internal representation of a set member is a bit.
« Last Edit: December 12, 2018, 02:48:22 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Determine if a char
« Reply #13 on: December 12, 2018, 05:10:39 pm »
@440bx based on your code, a little bit more:
Code: Pascal  [Select][+][-]
  1. function CheckCharacters(aRec : string) : boolean;
  2. var
  3.   idx : integer;
  4. begin
  5.   for idx := 1 to length(aRec) do
  6.     if not (aRec[idx] in ['A'..'Z']) then exit(false);
  7.  
  8.   result := true;
  9. end;

or:
Code: Pascal  [Select][+][-]
  1. function CheckCharacters(aRec : string) : boolean;
  2. var
  3.   c : char;
  4. begin
  5.   for c in aRec do
  6.     if not (c in ['A'..'Z']) then exit(false);
  7.  
  8.   result := true;
  9. end;

Yes, those work too.  I like setting "result" explicitly at the function entry.

The first alternative generates code that is basically equivalent (code size and speed) as the code generated when setting result upfront.

I like the second alternative, very clean and maintainable but, it generates more code and it's also a smidgen slower.   I like the "c in ..." but I don't want to pay extra for it. ;)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Determine if a char
« Reply #14 on: December 12, 2018, 05:28:10 pm »
But I wonder why this thread moved away from Handoko's

Code: Pascal  [Select][+][-]
  1. if (Character < 'A') or (Character > 'Z') then

Model.
It was not intended. Not (c in ['A'..'Z']) is equivalent to it.

I would have thought it would be faster ?
Hard to tell with modern CPUs.

By testing against the set of 'A'..'Z' we'd do 26 comparisons
It takes the ordinal value of the character (it has this value already), subtracts the ordinal value of the first character in the range 'A' (65) and compares with number of characters in the range (26).

 

TinyPortal © 2005-2018