#21 2009-02-16 09:16

prologician
Member
Registered: 2009-01-30
Posts: 84

Re: UserInput Letters a to zz

Hehe. The idea of the ALPHA_FORMAT was to allow exactly that... mixing of character sets. It depends on what you're aiming for, but if you don't need to mix and match, that's fine.

As far as your current IsNumber, IsUpperCaseLetter, etc., you could probably substitute those with the built-in functions IsWideCharDigit, IsWideCharUpper, etc. Minor point of cleanup, entirely up to you. smile

As far as how it works... the array SerialCount is a blob of integers, one integer per character in the resulting serialization. You increment index 0, which corresponds to the lowest position in the serialization. CheckCarries() checks if each number is actually within the bounds of the character set for that position. If it is, great; if not, it does like what you were taught in elementary school.... add a carry to the next column over. smile

Once the values are all updated, AlphaSerialize() translates each integer to a matching letter, collects them all together, and returns the resulting serialization string. smile The remaining critters are helper functions which are hopefully instructive by their name. smile

Offline

#22 2009-02-16 09:53

report
Member
Registered: 2009-01-05
Posts: 40

Re: UserInput Letters a to zz

I suspected that there might be such built-in functions in Pascal, but programming these again was faster than looking up manuals :) Thank you for the background explanations; this will make it easier to understand the semantics!

Offline

#23 2009-02-16 18:42

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: UserInput Letters a to zz

OK, I hope it's final version.
I went for a small  unification with your scripts, guys. So now we have same letterset's constant names. Just for case that someone want's to use both scripts. It will be less confusing.
I did some cleaning. And there it is.

If the letterset is 'abc', serialization goes like this:
a
b
c
aa
ab
ac
ba... and so on.

The main difference between mine and prologician's script is that mine goes only through the defined (but only one) letterset. No number-padding when you exceed the pattern.
BTW, prologician, maybe you should give user a possibility to chose padding from any given letterset,
eg. PADDING = LETTERS_U;
I think, I will give up tweaking it now. It was nice exercise.
Cheers.

CONST 
  LETTERS_L = 'abcdefghijklmnopqrstuvwxyz';
  LETTERS_U = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  NUMBERS = '0123456789';
  BOTH_NL = '0123456789abcdefghijklmnopqrstuvwxyz';
  BOTH_NU = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
TEST = 'abcde';



//CONTROLS FOR THE SCRIPT:
SERIALIZE = LETTERS_L;             //setting the letterset for serialization
START_PATTERN = 'a';             //anything you want to start with, eg. 'bba'
STEP = 1;                       //step MUST be lower than length of SERIALIZE string


var
  i, k: Integer;
  Pad: Array of Integer;    //Pad array is 0 based, but it stores values only from index 1
  Initialized: Boolean;
Start, Serialization : WideString;
  


procedure Initialize;
begin
  Initialized := True;
  Start:='';
  Start:=Start+START_PATTERN;
 
        
  SetLength(Pad, Length(Start)+1);
  Pad[0] := -1;      // just in case, we won't use that cell  
  

  if Length(Pad) < 2 then
    ShowMessage('Error:'+#13+'START_PATTERN constant not defined.'+#13+'Set START_PATTERN constant to '+#39+'a'+#39)
  else if Length(Pad) = 2 then
    begin
      Pad[1] := WidePos(Start[1], SERIALIZE);
      If Pad[1] = 0 then 
        ShowMessage('Error:'+#13+'START_PATTERN constant contains a char ('+#39+Start[1]+#39+'), that is not present in SERIALIZE constant!');
    end
  else
    for k:=1 to Length(Pad)-1 do  
      begin
        Pad[k] := WidePos(Start[k], SERIALIZE);
        if Pad[k] = 0 then 
          ShowMessage('Error:'+#13+'START_PATTERN constant contains a char ('+#39+Start[k]+#39+'), that is not present in SERIALIZE constant!');
      end;
  ;

  i := WidePos(Start[Length(Pad)-1], SERIALIZE);  
end;



procedure CheckZ(p:Integer);
begin

if Pad[p] > Length(SERIALIZE) then
begin
  Pad[p]:=1;
  if p > 1 then
  begin
    Pad[p-1]:=Pad[p-1]+1;
    CheckZ(p-1);
  end
  else
    SetLength(Pad, Length(Pad)+1);
end;

end;


begin
  if not Initialized then Initialize;


  Pad[Length(Pad)-1]:=i;  
  if i > Length(SERIALIZE) then
  begin
    CheckZ(Length(Pad)-1); 
    i:=i-Length(SERIALIZE);
    Pad[Length(Pad)-1]:=i;
  end;
  



  Serialization:='';
  for k:=1 to Length(Pad)-1 do                       
    Serialization:=Serialization + SERIALIZE[Pad[k]];
  
  
  FileName := WideStripExtension(FileName)+ Serialization + WideExtractFileExt(FileName);  
  i := i + STEP;
end.

Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#24 2009-02-16 21:31

prologician
Member
Registered: 2009-01-30
Posts: 84

Re: UserInput Letters a to zz

Strictly speaking, the capacity to change the overflow padding already there, I was just too lazy to make it an explicit constant.... In the NthInFormatToLetterset() function:

  if (I >= length(Format)) then
  begin
    result := NUMBERS;
    exit
  end;

Change 'NUMBERS' to whatever other alphabet set you want will get you there. Or, if you REALLY want it, you could pull out another constant for handling this. Entirely up to you. smile

Last edited by prologician (2009-02-16 21:54)

Offline

#25 2009-02-17 07:03

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: UserInput Letters a to zz

prologician wrote:

the capacity to change the overflow padding is already there

I thaught so wink
Frankly speaking I can hardly believe I will ever use mine or yours script for actual renaming. I prefer numbers for serialization.
But it was nice exercise.

Last edited by krtek (2009-02-17 07:03)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#26 2009-02-18 19:29

Andrew
Senior Member
Registered: 2008-05-22
Posts: 542

Re: UserInput Letters a to zz

krtek, in your script above, if I specify START_PATTERN = 'Z9x', then after 'Z9z', it shows 'ZA0'.

prologician's script on the other hand shows '0A0a' or 'aA0a' (depending on whether result := NUMBERS; or result := LETTERS_L as discussed just above).

When I was independently thinking of the logic, I too thought that 'Z9z' should be followed by 'aA0a'. Anyway, it all depends on what the user wants. Both scripts are simply fantastic! smile

BTW, since I too felt that this would be a nice programming exercise and a way to improve my PascalScript skills, here's my contribution:

{ Alphanumeric Serialization Script }

// v1 - Original script by Andrew

const
  digit_low = 48;   // 0
  digit_high = 57;  // 9
  ucase_low = 65;   // A
  ucase_high = 90;  // Z
  lcase_low = 97;   // a
  lcase_high = 122; // z

  initstr = 'a';        // Set initial string here
  overflow = lcase_low; // Set overflow char here
  step = 1;             // Set step value here
  append = True;        // Append serialized string?
  skipext = True;       // Skip file extension?

var
  s1,s2: String;
  i,low,high,val: Integer;
  initialized,carry: Boolean;

procedure SetFileName;
begin
  if(append) then
  begin
    if(skipext) then
      FileName := WideExtractBaseName(FileName) + s2 + WideExtractFileExt(FileName)
    else
      FileName := FileName + s2;
  end
  else
    FileName := s2 + FileName;
end;

begin
  if(Not initialized) then
  begin
    s2 := initstr;
    for i := 1 to Length(s2) do
      s1 := s2[i] + s1;
    SetFileName;
    initialized := True;
    Exit;
  end;
  for i := 1 to Length(s1) do
  begin
    if((i>1) And (Not carry)) then
      Break;
    val := Ord(s1[i]);
    if(val >= lcase_low) then // Lower-case
    begin
      low := lcase_low;
      high := lcase_high;
    end
    else if(val >= ucase_low) then // Upper-case
    begin
      low := ucase_low;
      high := ucase_high;
    end
    else if(val >= digit_low) then // Digit
    begin
      low := digit_low;
      high := digit_high;
    end;
    if(Not carry) then
      val := val + step;
    carry := False;
    if(val > high) then
    begin
      while(val > high) do
        val := low + (val mod high) - 1;
      if(i = Length(s1)) then
      begin
        SetLength(s1, Length(s1)+1);
        s1[i+1] := Chr(overflow);
      end
      else
      begin
        s1[i+1] := Chr(Ord(s1[i+1]) + 1);
        carry := True;
      end;
    end;
    s1[i] := Chr(val);
  end;
  s2 := '';
  for i := 1 to Length(s1) do
    s2 := s1[i] + s2;
  SetFileName;
end.

If someone can, please stress test it and give your comments. Thanks! smile

Last edited by Andrew (2009-02-18 20:04)

Offline

#27 2009-02-18 21:45

krtek
Senior Member
From: Łódź (Poland)
Registered: 2008-02-21
Posts: 262

Re: UserInput Letters a to zz

Andrew wrote:

krtek, in your script above, if I specify START_PATTERN = 'Z9x', then after 'Z9z', it shows 'ZA0'.
prologician's script on the other hand shows '0A0a' or 'aA0a' (depending on whether result := NUMBERS; or result := LETTERS_L as discussed just above).

To be honest I haven't notice the difference... Just tested, and prologician's script (with pattern 'BBb' and initial string 'Z9x') gives ZA0 after Z9z...

And about the logic... It's quite hard to aknowledge that... I haven't thought about logic. Mainly, because I can't find any particular use of such (letters+numbers) serialization (I prefer numbers). My main goal was to recreate the list created by report at the very beginning.
BOTH_NL and BOTH_NU serialization strings were taken by me from prologician's script to give user some unification of interface.
The cold truth is that anyone who decides to use one of BOTH type serialization strings,  have to decide what was first (egg or hen?).  And make adjustments to these strings. They can start with 0 with 1 or with a (and then after z can be 0 or 1)...
Do it like you like it wink


Andrew wrote:

If someone can, please stress test it and give your comments.

It looks to work fine if overflow char is a letter of same case as in initial string.
It looks a bit funny with 'a' as initial string and 'A' as overflow char (or other way round).
It's quite strange with digits as overflow... It seems to work the other work round then.  x,y,z, 0a, 0b, 0c... 9x, 9y, 9z, 00a, 00b, 00c...


Nice idea with append and skipext constants. But I guess you should explain "append" a bit better in comments eg. true - at the beggining, false - at the end... (I hate naming const and vars and adding comments, I never know how to make all that meaningful enough for user). Overflow char is quite mystic and not very well explained const, too.

Just few first thoughts.

It has started as an example of hard typing work and ended as PascalScript self-e-learning course lol

Cheers,
Konrad

Last edited by krtek (2009-02-18 21:46)


Regular Expressions are not as hard to understand as you may think. Check ReNamer's manual or nice Regular Expressions tutorial for more info and start to use full power of applications that use them (like ReNamer, Mp3Tag and so on).

Offline

#28 2009-02-19 06:29

report
Member
Registered: 2009-01-05
Posts: 40

Re: UserInput Letters a to zz

Just some motivation for why one one might serialize alphanumeric:

My most frequent application is to have countless media files. Different contents gets different file numbers. However, I also want to group almost-same contents (like a picture with same motif but edited for brightness or like a music track but edited to be without scratches). Then I use the same file number but append serialized letters.

It does sometimes happen though that I need speaking filenames plus counter. Like MySpeakingNameNNN. Then it is fast to do that in one step by starting from MySpeakingName000.

Of course, I try to avoid w0I1l2D3 file names. But, from a programming POV, it has been the almost same work to allow both MySpeakingName000 or w0I1l2D3 as starting values. So there is no reason not to offer it in all generality. And there is no reason to require two rules (Insert MySpeakingName + Append Serialize From 000) when one rule (Serialize from MySpeakingName000) suffices! File renaming must be as efficient as anyhow possible because in practice one wants to work with contents rather than spending lots of time on file renaming:)

Offline

#29 2009-02-19 07:17

report
Member
Registered: 2009-01-05
Posts: 40

Re: UserInput Letters a to zz

Andrew, your script (and its straightforward design) seems to work as well. How many roads are there to Rome...? However, if one restricts the letterset to, say, {a, b} by lcase_high = 98 and then uses an initstring with also other letters, say, MyNamea, then one is reminded of Pacman: The name is eaten up in a peculiar manner:( Such does not happen with prologician's or my scripts.

I agree though that more options for where to insert or the extension should be added but do not like your selective choice here. It is more a proof of concept so far.

Practically speaking, users will find editing letterset strings easier than ascii code numbers. But... when alphaserialize becomes hardcoded, such does not matter any longer.

Offline

#30 2009-02-19 11:53

prologician
Member
Registered: 2009-01-30
Posts: 84

Re: UserInput Letters a to zz

As far as the script is concerned, I'm with krtek on this one. It was a rather interesting exercise, though it's not something I myself would use on any regular basis at all. But, if it makes your life easier, report, then by all means. *^_^*

I do wonder, in a way, if such a thing will get built into Renamer itself, though. I mean, one way to look at all our scripts is as a proof-of-concept. Another way is that they are functional code, doing the job to a (hopefully reasonable) degree. Combining this with my belief that, due to the inclusion of PascalScript within a program like ReNamer, that you really can do virtually anything (I mean, we got a couple scripts here that call actual DLLs.... if that's not power in your hands, I don't know what is)... any of the answers proposed in this thread are probably more than enough for most folks' needs. smile

Of course, this isn't to say that den4b ~couldn't~ include an AlphaSerialize function into some future version. I'm figuring it's more likely that using one of these scripts will be more likely to happen. smile

Offline

Board footer

Powered by FluxBB