Skip to content

Instantly share code, notes, and snippets.

@Cicolas
Last active December 4, 2022 18:44
Show Gist options
  • Save Cicolas/fae0cd367c18769f59cf1ff0b7f5b8e4 to your computer and use it in GitHub Desktop.
Save Cicolas/fae0cd367c18769f59cf1ff0b7f5b8e4 to your computer and use it in GitHub Desktop.
concantena todos arquivos de uma pasta com as resoluções de exercicios para um so
#!/usr/bin/env python3
# Nícolas dos Santos Carvalho
# UEM 2022
# Esse programa concatena todos os arquivos de uma dada pasta
# afim de criar somente um com todos os exercicios resolvidos
#
#?EXEMPLO:
# trabalhos/
# ├─ fruber/
# │ ├─ 01122022_01.c
# │ ├─ 01122022_02.c
# ├─ codeX.py
#
# ./fruber/01122022_01.c:
# //@start include
# //@once stdio
# #include <stdio.h>
# //@once math
# #include <math.h>
# //@end
#
# int main(void) {
# //@start main
# printf("exercicio 1")
# //@end
#
# return 0;
# }
#
# ./fruber/01122022_02.c:
# //@start include
# //@once stdio
# #include <stdio.h>
# //@end
#
# int main(void) {
# //@start main
# printf("exercicio 2")
# //@end
#
# return 0;
# }
#
# trablhos> ./codeX.py ./fruber
#
# ./fruber/out.c:
# #include <stdio.h>
# #include <math.h>
#
# int main(void) {
# // 1)
# {
# printf("exercicio 1")
# }
#
# // 2)
# {
# printf("exercicio 2")
# }
#
# return 0;
# }
#
#!obs.: EU NÃO SEI PROGRAMAR EM PYTHON ESSE CÓDIGO PROVAVELMENTE POSSUI BUGS
#! E MESMO SEM SABER EU SEI QUE ESTÁ TERRIVELMENTE MAL PROGRAMADO
#! FIQUE À VONTADE PARA MUDAR E FAZER O QUE QUISER COM ELE
#
#!todos os arquivos devem serem finalizados com ..._xx.c
# DECORADORES PARA O CÓDIGO
# @once - adiciona somente uma vez
# @ignore - ignora a linha abaixo
# @start - começa uma área (include, defs, explain, explain-all, main, functions)
# @end - finaliza a área
from datetime import date
import sys
import os
import re
################################################################################
def mapLines(l):
"""
Faça aqui oque quiser com as linhas!
a string que for passada aqui passa para filtragem e depois é salva no arquivo
"""
return l
def filterLines(l):
"""
Filtre as linhas do jeito que quiser aqui! (acontece depois do map)
se retornar verdadeiro a linha será salva no arquivo, caso falso não será
"""
return True
################################################################################
partsCombined = {
"explain-all": "",
"include": "",
"defs": "",
"main": "",
"explain": "",
"functions": ""
}
def main(argv):
if len(argv) <= 1:
print("ERRO: Precisa de um caminho para concatenar os arquivos, porém nenhum argumento foi passado")
return 1
folderPath = argv[1]
filesName = os.listdir(
os.path.join(folderPath)
)
fileregex = r".*_\d{2}\.c"
filesName = list(filter(
lambda f: re.match(fileregex, f),
filesName
))[::-1]
for f in filesName:
# message(os.path.join(folderPath, f), 0)
fileNumber = re.search(r"(?<=_)\d{2}(?=\.c)", f).group()
interp = Interpreter()
interp.interpretFiles(os.path.join(folderPath, f))
setupParts(interp.partitions, fileNumber)
writeFile(os.path.join(folderPath), partsCombined)
return 0
def writeFile(filePath, parts):
today = date.today()
with open(os.path.join(filePath, "./out.c"), "w") as file, open("./.templates/trabalho.c") as template:
templ = template.replace("$DD", f"{today.day:02}"
).replace("$MM", f"{today.month:02}"
).replace("$AAAA", f"{today.year:04}"
).replace("$INCL", parts["include"]
).replace("$EXPL", parts["explain-all"]
).replace("$MAIN", parts["main"]
).replace("$DEFS", parts["defs"]
).replace("$FUNC", parts["functions"])
templ = "\n".join(
list(filter(
filterLines,
list(map(
mapLines,
templ.replace("\r", "").split("\n")
))
))
)
templ = re.sub(r"\n{2,}", "\n\n", templ)
file.write(templ)
def setupParts(parts, exNumber):
# print(exNumber, parts)
partsCombined["include"] += parts["include"]
body = (
f" // {exNumber}\n"+
" {\n"+
increaseIdentation(parts["explain"], 8) + "\n" +
increaseIdentation(parts["main"], 4) +
"}\n\n"
)
partsCombined["main"] += body
def increaseIdentation(str, space):
return (" "*int(space))+str.replace("\n", "\n"+(" "*space))
onceList = {}
class Interpreter:
opts = {
"strict": True
}
def __init__(self):
self.partitions = {
"explain-all": "",
"explain": "",
"include": "",
"defs": "",
"main": "",
"functions": ""
}
def interpretFiles(self, filePath):
with open(filePath, 'r') as f:
data = f.readlines()
i = 0
while i < len(data):
d = self.parseData(data, i)
i = d["index"] + 1
if self.opts["strict"]:
if d["type"] == "start":
self.partitions[d["name"]] += d["value"]
else:
#TODO: implementar in-line (non strict mode)
pass
def parseData(self, lines, i):
line = lines[i]
lineTrimed = line.strip()
if lineTrimed.startswith("//@ignore"):
return {"index": i+1, "type": "ignore", "value": ""}
elif lineTrimed.startswith("//@once "):
name = re.search(r"((?<=//@once )[a-zA-Z_]*)", lineTrimed).group()
if name in onceList:
onceList[name] += 1
print(i if onceList[name] == 1 else i+1)
else:
onceList[name] = 1
return {
"index": i if onceList[name] == 1 else i+1,
"type": "once",
"value": ""
}
elif lineTrimed.startswith("//@start "):
name = re.search(r"((?<=//@start )[a-zA-Z_]*)", lineTrimed).group()
d = {"type": ""}
l = ""
body = ""
while d["type"] != "end":
i += 1
d = self.parseData(lines, i)
l = d["value"]
body += l if l.strip() != "\r\n" else ""
i = d["index"]
# print("//@start "+name+":\n"+body)
return {"index": i, "type": "start", "name": name, "value": body}
elif lineTrimed.startswith("//@end"):
return {"index": i, "type": "end", "value": ""}
return {"index": i, "type": "line", "value": line}
if __name__ == "__main__":
try:
main(sys.argv)
print("Programa executado com sucesso")
except:
print("Programa retornou erros")
input("Aperte 'Enter' para fechar")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment