Menu

newbee and basic algorithm

Help
saih_tam
2022-01-18
2022-01-25
  • saih_tam

    saih_tam - 2022-01-18

    Hello

    I'm sorry for my bad english.

    I used to use perso Notepad++ macros : I just record what I do using keyboard, keyboard shortcuts and the mouse only to clic on 'close (cross) button' of find window. It often helps me to save a lot of time in order to modify semi automatically a lot of files 'song.ini' (arround 5000).

    Unfortunatly, I’m stuck on the impossibility of using basing conditional tests. I understood that PythonScript plugin in Notepad++ allow this conditionnal tests (and far more).
    I never used Python and it would take me a lot of time to code my basic algorithm. For a regular, this will probably only take an hour or less.

    I wrote my basic algorithm (Algorithme rename.txt) and I hope somebody could code it entirely or help me for the Python part. I have already record a macro (Algorithme rename shortcuts.xml) which is likely what I want without conditionnal tests.

    Regards

    I attach 1 zip file contains :
    - exemple1 song.ini
    - exemple2 song.ini
    - Algorithme rename.txt
    - Algorithme rename shortcuts.xml

     
  • saih_tam

    saih_tam - 2022-01-22

    Algorithme rename :

    Start macro
    
    'ctrl' + 'f'; ### open 'find window'
    'n' 'a' 'm' 'e' ' ' '=' 'enter'; ### find("name =")
    
    If (find("name =") == true) :
        clic on 'close (cross) button'; ### close find window
        'end' ### go to line's end with key '1' of numeric keypad 
        'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
        'shift' + 'left arrow'; ### ... and select the precedent line break
        'ctrl' + 'x'; ### cut selection
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'ctrl' + 'v'; ### paste selection
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    Else :
        clic on 'close (cross) button'; ### close find window
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'enter' 'n' 'a' 'm' 'e' ' ' '=' ' '; ### create a newline and write "name = "
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    
    
    'ctrl' + 'f'; ### open 'find window'
    'a' 'r' 't' 'i' 's' 't' ' ' '=' 'enter'; ### find("artist =")
    
    If (find("artist =") == true) :
        clic on 'close (cross) button'; ### close find window
        'end' ### go to line's end with key '1' of numeric keypad 
        'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
        'shift' + 'left arrow'; ### ... and select the precedent line break
        'ctrl' + 'x'; ### cut selection
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'ctrl' + 'v'; ### paste selection
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    Else :
        clic on 'close (cross) button'; ### close find window
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'enter' 'a' 'r' 't' 'i' 's' 't' ' ' '=' ' '; ### create a newline and write "artist = " 
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    
    
    'ctrl' + 'f'; ### open 'find window'
    'a' 'l' 'b' 'u' 'm' ' ' '=' 'enter'; ### find("album =")
    
    If (find("album =") == true) :
        clic on 'close (cross) button'; ### close find window
        'end' ### go to line's end with key '1' of numeric keypad 
        'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
        'shift' + 'left arrow'; ### ... and select the precedent line break
        'ctrl' + 'x'; ### cut selection
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'ctrl' + 'v'; ### paste selection
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    Else :
        clic on 'close (cross) button'; ### close find window
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'enter' 'a' 'l' 'b' 'u' 'm' ' ' '='  ' '; ### create a newline and write "album = " 
        'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    
    ### Do the same routine for 'genre = ', 'year = ', 'track = ', 'loading_phrase = ', 'charter = ', 'frets = '
    ### And the last
    
    'ctrl' + 'f'; ### open 'find window'
    's' 'o' 'n' 'g' '_' 'l' 'e' 'n' 'g' 't' 'h' ' ' '=' 'enter'; ### find("song_length =")
    
    If (find("song_length =") == true) :
        clic on 'close (cross) button'; ### close find window
        'end' ### go to line's end with key '1' of numeric keypad 
        'shift' + 'home'; ### select all the line with key '7' of numeric keypad...
        'shift' + 'left arrow'; ### ... and select the precedent line break
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'ctrl' + 'v'; ### paste selection
    Else :
        clic on 'close (cross) button'; ### close find window
        'ctrl' + 'pg up'; ### go to precedent tab with key '9' of numeric keypad
        'enter' 's' 'o' 'n' 'g' '_' 'l' 'e' 'n' 'g' 't' 'h' ' ' '='  ' '; ### create a newline and write "song_length = "
    
    'ctrl' + 'a'; ### select all the lines
    'left arrow'; ### go to start of 'buffer.txt'
    'delete'; ### delete the empty first line
    'ctrl' + 'a'; ### select all the lines
    'ctrl' + 'x'; ### cut selection
    'ctrl' + 'pg dn'; ### go to next tab with key '3' of numeric keypad
    'ctrl' + 'a'; ### select all the lines
    'left arrow'; ### go to start of 'song.ini'
    'end' ### go to first line's end with key '1' of numeric keypad
    'enter'; ### create a newline
    'ctrl' + 'v'; ### paste selection with key '3' of numeric keypad
    'ctrl' + 'a'; ### select all the lines
    'left arrow'; ### go to start of 'song.ini'
    
    End macro
    
     
  • saih_tam

    saih_tam - 2022-01-22

    Exemple1 before modification :

    [song]
    artist = Erasure
    name = 04B.103.8e Always (2009 Remix)
    album = Pop! Remixed
    delay = 3050
    diff_guitar = -1
    diff_bass = -1
    diff_guitar_coop = -1
    diff_rhythm = -1
    diff_vocals = -1
    diff_keys = -1
    diff_bass_real = -1
    diff_guitar_real = -1
    diff_dance = -1
    diff_bass_real_22 = -1
    diff_guitar_real_22 = -1
    diff_vocals_harm = -1
    sysex_high_hat_ctrl = True
    multiplier_note = 116
    pro_drums = True
    charter = BobSchneeder45
    background = imageWS.jpg
    last_play = 2022-01-16-22:36:05
    song_length = 245282
    

    Exemple1 after modification :

    [song]
    name = 04B.103.8e Always (2009 Remix)
    artist = Erasure
    album = Pop! Remixed
    genre = 
    year = 
    track = 
    loading_phrase = 
    charter = BobSchneeder45
    frets = 
    song_length = 245282
    delay = 3050
    diff_guitar = -1
    diff_bass = -1
    diff_guitar_coop = -1
    diff_rhythm = -1
    diff_vocals = -1
    diff_keys = -1
    diff_bass_real = -1
    diff_guitar_real = -1
    diff_dance = -1
    diff_bass_real_22 = -1
    diff_guitar_real_22 = -1
    diff_vocals_harm = -1
    sysex_high_hat_ctrl = True
    multiplier_note = 116
    pro_drums = True
    background = imageWS.jpg
    last_play = 2022-01-16-22:36:05
    

    Picture Illustrates before/after :

     

    Last edit: saih_tam 2022-01-22
  • saih_tam

    saih_tam - 2022-01-23

    I re-wrote my algorithm to simplify it :

    Open : 'song.ini'
    Desactivate 'back line auto' in 'display'
    Desactivate numeric keypad
    
    
    Start macro
    
    # move "name ="
    If (find("name =") == true) :
        cut ("name =" line with precedent line break) and paste it after ("[song]" line);
    Else :
        create a line after ("[song]" line) and write "name = ";
    
    # move "artist ="
    If (find("artist =") == true) :
        cut ("artist =" line with precedent line break) and paste it after ("name =" line);
    Else :
        create a line after ("name =" line) and write "artist = ";
    
    # move "album ="
    If (find("album =") == true) :
        cut ("album =" line with precedent line break) and paste it after ("artist =" line);
    Else :
        create a line after ("artist =" line) and write "album = ";
    
    
    # Do the same routine to move "genre = ", "year = ", "track = ", "loading_phrase = ", "charter = ", "frets = "
    # And the last
    
    # move "song_length ="
    If (find("song_length =") == true) :
        cut ("song_length =" line with precedent line break) and paste it after ("frets =" line);
    Else :
        create a line after ("frets =" line) and write "song_length = ";
    
    # move cursor to the first line to make easier the visual check before close/save or close/non-save
    'ctrl' + 'a'; # select all the lines
    'left arrow'; # move cursor to the start of 'song.ini'
    
    End macro
    

    An idea ?

     
  • saih_tam

    saih_tam - 2022-01-25

    I’m extremely grateful to @mpheath who gave me the solution “clé en main” (ready to use). I have understood it thanks to his explanations. I have implemented both Notepad++ Python Script and Standalone recursive Python Script : both work perfectly.
    I might even consider changing more elements very easily (thanks to list ‘presets’), and, amazing, modify the 5000 files without open them in Notepad++ (a lot of time saving). That’s a lot more than I expected.

    BIG THANKS to @mpheath and other for contributions at :
    https://community.notepad-plus-plus.org/topic/22412/newbee-macros-and-basic-algorithm-with-python-script/32

    I share with you the two scripts in final version.
    The Notepad++ Python Script :

    # coding: utf8
    # -*- coding: utf-8 -*-
    # Here is PythonScript to replace the text in the current editor pane.
    
    def ini_reindex():
    
        # Get text from the editor pane.
        text = editor.getText()
    
        if text == '':
            return ''
    
        # Presets ordered as the top-most keys.
        presets = ['name', 'artist', 'album', 'genre', 'year', 'track',
                   'loading_phrase', 'charter', 'frets', 'song_length']
    
        # Create a list of indexed lines.
        lines = [[-1, line.replace('\n', '')] for line in text.splitlines()]
        # Creates a list of lists like [[-1, 'Line 1'], [-1, 'Line 2'], [-1, 'Line 3'], ...]
        # The -1 will be replaced with numbers to order the lines later for sorting.
    
        # Add preset keys if not found.
        for item in presets:
            for line in lines:
                if line[1].startswith(item + ' = '):
                # item is each of presets list of ['name', 'artist', 'album', 'genre', 'year', 'track', 'loading_phrase', 'charter', 'frets', 'song_length']
                # So 1st one it trys to match is start with name = . Then tries artist = … until all items are tried. If break does not occur, then the else happens and the item key is added to the list.
                    break
            else:
                lines.append([-1, item + ' = '])
                # lines is a list and .append is a method to add to the list.
                # If the else ocurrs for not finding example 'name = ', then [-1, 'name = '] is added to the list.
    
        # Index the preset keys.
        index = 0
    
        for item in presets:
            for line in lines:
                if line[0] == -1:
                # This is lines with a -1 index, not given a line number yet. If starts with [ (section header) or item + ' = ' assign a line number to line[0], which is replace the -1 with a line number. index is the line number so index += 1 increments the number by adding 1.
                    if line[1].startswith('[') or line[1].startswith(item + ' = '):
                        line[0] = index
                        index += 1
    
        # Index the remaining keys.
        for line in lines:
            if line[0] == -1:
                line[0] = index
                index += 1
    
        # Sort by index.
        # Sorting the list of lists lines by the first element [0]. lambda is like a nameless function. The sort will look at example [[2, 'Line 2'], [1, 'Line 1']] so it sees the 1 and shifts it into 1st place and then 2 for 2nd place. This gets the list into the order that is wanted.
        lines.sort(key=lambda x: x[0])
    
        # Create text from lines.
        text = ''
    
        for line in lines:
            text += line[1] + '\n'
    
        return text
    
    # __name__ is the name of the running script. If named __main__, run the following code.
    # ini_reindex() is the function call and the returned value is saved in text. If the text returned is not an empty string, then call editor.setText(text) to replace edit pane contents with the value of text.
    if __name__ == '__main__':
        text = ini_reindex()
    
        if text != '':
            editor.setText(text)
    

    And the Standalone recursive Python Script :

    import glob
    
    # Presets ordered as the top-most keys.
    presets = ['name', 'artist', 'album', 'genre', 'year', 'track',
               'loading_phrase', 'charter', 'frets', 'song_length']
    
    # Start processing each 'song.ini' file.
    print('file:')
    
    # for file in glob.iglob('song.ini'): # This will do 'song.ini' in current directorie.
    for file in glob.iglob(r'**\song.ini', recursive=True): # This will do 'song.ini' in current and subdirectories.
        print(' ', file)
    
        # Read the 'song.ini' file and create a list of indexed lines.
        with open(file, 'r', encoding='utf8') as r:
            lines = [[-1, line.replace('\n', '')] for line in r]
    
        # Add preset keys if not found.
        for item in presets:
            for line in lines:
                if line[1].startswith(item + ' = '):
                    break
            else:
                lines.append([-1, item + ' = '])
    
        # Index the preset keys.
        index = 0
    
        for item in presets:
            for line in lines:
                if line[0] == -1:
                    if line[1].startswith('[') or line[1].startswith(item + ' = '):
                        line[0] = index
                        index += 1
    
        # Index the remaining keys.
        for line in lines:
            if line[0] == -1:
                line[0] = index
                index += 1
    
        # Sort by index.
        lines.sort(key=lambda x: x[0])
    
        # Save 'song.ini' file.
        with open(file, 'w', encoding='utf8') as w:
            for line in lines:
                w.write(line[1] + '\n')
    
    print('done')
    
     

    Last edit: saih_tam 2022-01-25

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.