B4J Question read/write python file

Michael1968

Active Member
Licensed User
Longtime User
Hi all...
..i have to read a python config file -> change the value ->write it back
the file looks like:

[Logging]
ch0 = True
ch1 = True
ch2 = True
ch3 = True
ch4 = True
ch5 = True
ch6 = True
ch7 = True
ch8 = True
ch9 = True
ch10 = True
ch11 = True
separator = ,
write_new_log_on_restart = False

[web_alert]
ch0 = False
ch1 = False
ch2 = False
ch3 = False
ch4 = False
ch5 = False
ch6 = False
ch7 = False
ch8 = False
ch9 = False
ch10 = False
ch11 = False

i have use map/list example with key/value but it seem i am on the wrong way.
any idea is welcome

Michael
 

stevel05

Expert
Licensed User
Longtime User
This will work if you only want to change 1 value, or you could run it through multiple times.:

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show

    'Setup for testing
    Dim Data As String = $"[Logging]
ch0 = True
ch1 = True
ch2 = True
ch3 = True
ch4 = True
ch5 = True
ch6 = True
ch7 = True
ch8 = True
ch9 = True
ch10 = True
ch11 = True
separator = ,
write_new_log_on_restart = False

[web_alert]
ch0 = False
ch1 = False
ch2 = False
ch3 = False
ch4 = False
ch5 = False
ch6 = False
ch7 = False
ch8 = False
ch9 = False
ch10 = False
ch11 = False"$

Dim L As List = Regex.Split(CRLF,Data)

'File.ReadList(DirName,FileName) will provide data in a list

    Dim Group As String = "[Logging]"
    Dim ID As String = "ch7"
    Dim NewValue As String = "False"
  
    Dim OutData As List = ChangeData( L, Group, ID, NewValue)
  
    'Show the result
    For Each S As String In OutData
        Log(S)
    Next

'File.WriteList(NewDirName, NewFileName, OutData)

End Sub

Private Sub ChangeData(DataList As List, Group As String, ID As String, NewValue As String) As List

    Dim i As Int = 0
    Dim S  As String = DataList.Get(i)
    i = i + 1
    Do Until S = Group
        S = DataList.Get(i)
        i = i + 1
        If i = DataList.Size Then Return DataList ' Or whateveryou want to do on Group not found error
    Loop
  
    Log("Group " & Group & "found")
  
    For i = i To DataList.Size - 1
        Dim S As String = DataList.Get(i)
        If S.Trim.StartsWith(ID) Then
            DataList.set(i,ID & " = " & NewValue)
            Return DataList
        End If
      
        If S.StartsWith("[") Then Return DataList ' Or whatever you want to do on ID not found in group error
    Next
  
    Return DataList ' or do whatever you want to do if the ID is not found error (if it's the last group)
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Or if you want to parse the whole file and make multiple changes you could do something like:

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show

    'Setup for testing
    Dim Data As String = $"[Logging]
ch0 = True
ch1 = True
ch2 = True
ch3 = True
ch4 = True
ch5 = True
ch6 = True
ch7 = True
ch8 = True
ch9 = True
ch10 = True
ch11 = True
separator = ,
write_new_log_on_restart = False

[web_alert]
ch0 = False
ch1 = False
ch2 = False
ch3 = False
ch4 = False
ch5 = False
ch6 = False
ch7 = False
ch8 = False
ch9 = False
ch10 = False
ch11 = False"$

    Dim L As List = Regex.Split(CRLF,Data)

    'File.ReadList(dirName,FileName) will provide the file data in a list

    Dim MasterMap As Map = ParseData(L)
  
  
    'Amend the data
    Dim Group As String = "[Logging]"
    Dim M As Map = MasterMap.Get(Group)
  
    M.Put("ch7","False")
    M.Put("write_new_log_on_restart","True")

    Group = "[web_alert]"

    Dim M As Map = MasterMap.Get(Group)
  
    M.Put("ch11","True")

    'Reassemble the list
    Dim OutData As List
    OutData.Initialize
  
    For Each S As String In MasterMap.Keys
        OutData.Add("")
        OutData.Add(S)
        Dim Map1 As Map = MasterMap.Get(S)
        For Each K As String In Map1.Keys
            OutData.Add(K & " = " & Map1.Get(K))
        Next
    Next
  
    OutData.RemoveAt(0)

    For Each S As String In OutData
        Log(S & " ")  'In case there is an empty string just so the log shows it
    Next


    'File.WriteList(NewDirName, NewFileName, OutData)
End Sub

Private Sub ParseData(DataList As List) As Map


    Dim MasterMap As Map
    MasterMap.Initialize

    Dim M As Map
    For Each S As String In DataList
        S = S.Trim
      
        If S = "" Then Continue
      
        If S.StartsWith("[") Then
            Dim Map1 As Map
            Map1.Initialize
            M = Map1
            MasterMap.Put(S,Map1)
            Continue
        End If
  
        If S.Contains("=") Then
            Dim Pos As Int = S.IndexOf("=")
            M.Put(S.SubString2(0,Pos).Trim, S.SubString(Pos+1).Trim)
        Else
            Log("format Error")
            Return CreateMap() 'Format Error return an empty map
        End If
    Next
  
    Return MasterMap
End Sub
 
Last edited:
Upvote 0
Top