Um dos grandes interesses da programação é automatizar tarefas simples. Um bom exemplo que encontrei foi a modificação de várias linhas de código num ficheiro INO para o Arduino.
Depois de escrever algumas dezenas de linhas de código em C++ para o meu projeto Arduino, dei por mim com um problema de memória que não conseguia resolver. Ao fazer alguma pesquisa, deparei-me com a função F(), que permite que cadeias de caracteres sejam colocadas na memória Flash. Isto poupa muito espaço quando Serial.print() é muito utilizado. Em vez de modificar o código à mão, escrevi um script python para inserir a função F() em Serial.print().
Descrição do método
Em primeiro lugar, é necessário abrir o ficheiro de destino antes de efetuar qualquer operação e, em seguida, não esquecer de o fechar quando terminarmos de o utilizar.
fileb=open( destfile, "w" ) fileb.close()
Em seguida, temos de percorrer o ficheiro original linha a linha.
with open(filename) as inofile: for line in inofile: print(line)
Quando for possível navegar no ficheiro, detectamos a presença de “Serial.print” e “Serial.println” em cada linha. Para o fazer, criamos uma função que devolve uma lista das posições destas cadeias de caracteres em cada linha.
def find_all_indexes(input_str, search_str): l1 = [] length = len(input_str) index = 0 while index < length: i = input_str.find(search_str, index) if i == -1: return l1 l1.append(i) index = i + 1 return l1
Para cada linha, se as cadeias de caracteres “Serial.print” e “Serial.println” não forem detectadas, escrevemos a linha no novo ficheiro tal como está.
if len(indexln)==0 and len(indexl)==0: fileb.write(line)
Caso contrário, modificamos primeiro as cadeias de caracteres “Serial.println” e depois as cadeias de caracteres “Serial.print”. Em cada caso, verificamos se a função F não está já presente. Se estiver, deixamos a linha inalterada e copiamo-la de volta para o ficheiro de destino.
if newl.find('F("')>0: pass
Caso contrário, detectamos a posição dos parênteses e das aspas e recuperamos a cadeia de caracteres
j=newl.find('("') k=newl.find('")') newlk=newl[j+1:k+1]
Finalmente, substituímos a cadeia recuperada pela mesma cadeia inserida na função F.
print("change String to F()-> "+'Serial.println(F('+newlk+'))') line=line.replace(newlk,'F('+newlk+')')
Antes de escrever a linha modificada no ficheiro de destino.
fileb.write(line)
Aqui está um bom exemplo de como usar um script Python para simplificar a sua vida. Não hesites em dizer-nos nos comentários se este tutorial foi útil para ti ou se encontras alguma coisa em falta, errada ou que precise de ser melhorada.
Código completo
Aqui está o código completo que pode copiar para testar. Tudo o que precisa de fazer é alterar os endereços do ficheiro de origem (filename) e do ficheiro de destino (destfile).
#!/usr/bin/python3.4 # -*-coding:Utf-8 -* def find_all_indexes(input_str, search_str): l1 = [] length = len(input_str) index = 0 while index < length: i = input_str.find(search_str, index) if i == -1: return l1 l1.append(i) index = i + 1 return l1 filename=".\Grab_Parts\Grab_Parts.ino" destfile=".\Grab_Partsb.ino" fileb=open( destfile, "w" ) with open(filename) as inofile: #data = file.read() for line in inofile: #print(line) #print(line.find("Serial.println")) indexln=find_all_indexes(line,"Serial.println") indexl=find_all_indexes(line,"Serial.print(") if len(indexln)==0 and len(indexl)==0: fileb.write(line) else: #change Serial.println for i in indexln: print("---------------------------------------------------") newl=line[i:] print(newl) if newl.find('F("')>0: pass else: j=newl.find('("') k=newl.find('")') newlk=newl[j+1:k+1] print(newlk) if( newlk.find('"')==0): print("change String to F()-> "+'Serial.println(F('+newlk+'))') line=line.replace(newlk,'F('+newlk+')') #print("Result ==> "+line) #fileb.write(line) #change Serial.print after indexl=find_all_indexes(line,"Serial.print(") for i in indexl: print("---------------------------------------------------") newl=line[i:] print(newl) if newl.find('F("')>0: pass else: j=newl.find('("') k=newl.find('")') newlk=newl[j+1:k+1] print(newlk) if( newlk.find('"')==0): print("change String to F()-> "+'Serial.print(F('+newlk+'))') #fileb.write('Serial.println(F('+newlk+'))') line=line.replace(newlk,'F('+newlk+')') print("Result ==> "+line) fileb.write(line) #print(indexl) fileb.close()
Possíveis melhorias
- Deteção automática de ficheiros INO numa árvore de directórios para modificar todos os ficheiros na mesma pasta