Форум сайта python.su
Доброго времени суток, я в питоне начинающий..
есть такой файл “GameMenu.res”, из игры counter-strike 1.6, в нем описано главное меню игры..
Я хочу иметь возможность изменять его(не создавать новый, а именно редактировать существующий).
Состоит он из главного слова Gamemenu, затем фигурные скобки {}
в главных фигурных скобках находятся элементы меню, они пронумерованы и содержат в себе несколько строк, которые так же находятся в фигурных скобках.
https://ltdfoto.ru/images/12d07c80fa4af2cd49.png
как я могу работать с подобным файлом?
Я не прошу код, просто толкните в правильную сторону..
Я не понимаю каким образом можно добавить новый блок, и перенумеровать остальные блоки.
Добавлять блоки нужно сверху, то-есть добавленный блок должен быть под номером 1:
“1”
{
…
…
…
}
Я могу так сделать, но получится 2 блока с названием “1”.
Я надеюсь внятно всё объяснил. Заранее благодарю.
Отредактировано z1g1zmund (Ноя. 28, 2021 14:54:09)
Офлайн
z1g1zmundПриведи файл точно. Используй теги code. Либо пиши через https://pastebin.com .
есть такой файл “GameMenu.res”, из игры counter-strike 1.6
Отредактировано py.user.next (Ноя. 28, 2021 21:49:23)
Офлайн
py.user.next
"GameMenu"
{
"1"
{
"label" "#GameUI_GameMenu_ResumeGame"
"command" "ResumeGame"
"OnlyInGame" "1"
}
"2"
{
"label" "#GameUI_GameMenu_Disconnect"
"command" "Disconnect"
"OnlyInGame" "1"
"notsingle" "1"
}
"4"
{
"label" "#GameUI_GameMenu_PlayerList"
"command" "OpenPlayerListDialog"
"OnlyInGame" "1"
"notsingle" "1"
}
"8"
{
"label" ""
"command" ""
"OnlyInGame" "1"
}
"9"
{
"label" "#GameUI_GameMenu_NewGame"
"command" "OpenCreateMultiplayerGameDialog"
}
"10"
{
"label" "#GameUI_GameMenu_FindServers"
"command" "OpenServerBrowser"
}
"11"
{
"label" "#GameUI_GameMenu_Options"
"command" "OpenOptionsDialog"
}
"12"
{
"label" "#GameUI_GameMenu_Quit"
"command" "Quit"
}
}
"GameMenu"
{
"1"
{
"label" "Конфиг с.cfg"
"command" "engine exec c.cfg"
}
"2"
{
"label" ""
"command" ""
}
"3"
{
"label" ""
"command" ""
}
"4"
{
"label" "#GameUI_GameMenu_ResumeGame"
"command" "ResumeGame"
"OnlyInGame" "1"
}
"5"
{
"label" "#GameUI_GameMenu_Disconnect"
"command" "Disconnect"
"OnlyInGame" "1"
"notsingle" "1"
}
"6"
{
"label" "#GameUI_GameMenu_PlayerList"
"command" "OpenPlayerListDialog"
"OnlyInGame" "1"
"notsingle" "1"
}
"7"
{
"label" ""
"command" ""
"OnlyInGame" "1"
}
"8"
{
"label" "#GameUI_GameMenu_NewGame"
"command" "OpenCreateMultiplayerGameDialog"
}
"9"
{
"label" "#GameUI_GameMenu_FindServers"
"command" "OpenServerBrowser"
}
"10"
{
"label" "#GameUI_GameMenu_Options"
"command" "OpenOptionsDialog"
}
"11"
{
"label" "#GameUI_GameMenu_Quit"
"command" "Quit"
}
}
Отредактировано z1g1zmund (Ноя. 28, 2021 23:35:56)
Офлайн
Тут надо работать просто с текстом.
Это надо сначала входной файл разделить на блоки по строкам. Типа заголовок, тело, подвал. Потом тело нужно разделить на блоки тоже по строкам. Блоком будет являться последовательность строк от цифрового названия в двойных кавычках до закрывающей фигурной скобки. После того как ты разделил, у тебя получается список блоков тела. И вот в этот список ты начинаешь вставлять дополнительные блоки (в начало, в конец, в середину, неважно куда). После того, как ты вставил блоки, ты запускаешь перенумератор, который просто заходит в каждый блок в этом списке и заменяет цифровое название блока на номер по порядку. После перенумерации у тебя есть заголовок всего файла, тело файла в виде списка перенумерованных блоков, подвал файла. И дальше ты это всё выводишь в отдельный файл вывода друг за другом. Так у тебя получается файл вывода. После этого ты берёшь файл ввода и удаляешь, а файл вывода переименовываешь в файл ввода. И так у тебя получается изменённый файл.
Сделаешь ли ты это сам на питоне? Ну, хрен знает, не думаю. Тут надо много функций всяких написать, которые и будут это дробить на блоки, перенумеровывать каждый блок, эти строчки искать для накопления блока. Без опыта, я не думаю, что ты напишешь хоть что-то приемлемое.
z1g1zmundЭто ты попросил тебя направить.
Я не прошу код, просто толкните в правильную сторону.
Отредактировано py.user.next (Ноя. 29, 2021 00:59:49)
Офлайн
py.user.nextДа, красивых решений тут похоже не получится.
Но я тоже тут не уверен, что оно красиво получится.
py.user.next
Просто писать надо так, чтобы при изменении каких-то вводных требований код не приходилось писать заново весь
Офлайн
doza_andДа я не думаю, что тут надо дерево строить. Можно всё сделать, построив просто плоскую структуру. Плоскую структуру с вложенной плоской структурой. Очень всё просто получится. Просто xam1816'у не хватит опыта. По задаче с выписками из ЕГРН это видно.
Да, красивых решений тут похоже не получится.
doza_andНаверное, вероятность того, что он не может это делать руками, высокая. Видимо, он делает это много раз или просто часто.
Из постановки задачи непонятно почему ТС не может это ручками один раз сделать.
doza_andДело в том, что завтра он скажет, что ему надо теперь блоки в середину вставлять. И тут-то простой сдвиг нумерации превратится в тыкву. Придётся тогда заново всё писать и делать уже всё по-нормальному. Так вот нумерацию можно проводить любым образом тогда, когда у тебя есть что нумеровать в виде такого составного объекта, состоящего из объектов, и над этим объектом можно построить путём расширения разные операции. Составной объект, который состоит из маленьких объектов. Так вот на этом составном объекте можно добавить его операцию перенумерации, которая при выполнении итеративно запускает у каждого маленького объекта его личную перенумерацию самого себя.
1 Нумерацию сдвинуть легко регулярными выражениями, если в качестве замены подать функцию.
doza_andДа соблазн такой есть. Но это мнимое спасение. Оно сильно исказит исходный файл. Оно может табуляцию, например, заменить на пробелы или вообще стереть всё нафиг, превратив в одну строку весь файл. И тут-то вдруг и окажется, что этот Counter Strike не может понять этот файл, потому что ждёт там блоками всё и с табуляциями. Ну, или там просто всё это станет нечитаемым человеком, а нужно, чтобы оно было читаемым и меняемым руками в том числе - чтобы и скриптом можно было всё поменять, и руками.
Если регулярками понавставлять двоеточий и запятых то из скобок получится или json
>>> import re >>> >>> class Document: ... def __init__(self, header, body, footer): ... self.header = header ... self.body = body ... self.footer = footer ... def __str__(self): ... return '{}\n{}\n{}'.format( ... self.header, ... self.body, ... self.footer ... ) ... >>> class DocumentHeader: ... def __init__(self, text): ... self.text = text ... def __str__(self): ... return 'header {{\n\t{}\n'.format(self.text) ... >>> class DocumentBody: ... def __init__(self, blocks): ... self.blocks = blocks ... def __str__(self): ... return '\n'.join(map(str, self.blocks)) ... def rename_blocks(self): ... for block in self.blocks: ... block.rename_to_number_add_1() ... block.rename_to_number_width(3) ... block.rename_to_prefix('<') ... block.rename_to_suffix('>') ... >>> class DocumentBodyBlock: ... def __init__(self, name, text): ... self.name = name ... self.text = text ... def __str__(self): ... return ('\tblock "{}" {{\n' ... '\t\t{}\n' ... '\t}}').format(self.name, self.text) ... def rename_to_prefix(self, text): ... self.name = text + self.name ... def rename_to_suffix(self, text): ... self.name = self.name + text ... def rename_to_number_add_1(self): ... self.name = re.sub( ... r'\d+', ... lambda mo: str(int(mo.group()) + 1), ... self.name ... ) ... def rename_to_number_width(self, n): ... self.name = '{:0{w}d}'.format(int(self.name), w=n) ... >>> class DocumentFooter: ... def __init__(self, text): ... self.text = text ... def __str__(self): ... return '\n\t{}\n}} footer'.format(self.text) ... >>> body_blocks = ( ... DocumentBodyBlock('1', 'block text 1'), ... DocumentBodyBlock('2', 'block text 2'), ... DocumentBodyBlock('3', 'block text 3'), ... DocumentBodyBlock('4', 'block text 4'), ... DocumentBodyBlock('5', 'block text 5') ... ) >>> body = DocumentBody(body_blocks) >>> >>> document = Document( ... DocumentHeader('header text'), ... body, ... DocumentFooter('footer text') ... ) >>> >>> out = str(document) >>> print(out) header { header text block "1" { block text 1 } block "2" { block text 2 } block "3" { block text 3 } block "4" { block text 4 } block "5" { block text 5 } footer text } footer >>> >>> body.rename_blocks() >>> >>> out = str(document) >>> print(out) header { header text block "<002>" { block text 1 } block "<003>" { block text 2 } block "<004>" { block text 3 } block "<005>" { block text 4 } block "<006>" { block text 5 } footer text } footer >>>
Отредактировано py.user.next (Ноя. 29, 2021 11:19:45)
Офлайн
class Document: def __init__(self, name): self.name = name self.blocks = [] def __str__(self): return '"{name}"\n{{\n{blocks}\n}}'.format(name=self.name, blocks=self.form_blocks()) # def form_blocks(self): text = ''.join(['\t"{}"\n{}'.format(n,str(b)) for n, b in enumerate(self.blocks, 1)]) return text # d = Document('GameMenu') # создаем документ без блоков print(d) print("===============================") # class Block: def __init__(self,**kwargs): self.kwargs = kwargs # def __str__(self): text = '\n'.join(['\t\t"{}" "{}"'.format(k, v) for k, v in self.kwargs.items()]) out = '\t{{\n{}\n\t}}\n'.format(text) return out # b = Block(label='GameUI_GameMenu_Disconnect',command='Disconnect') # создаем блок b2 = Block(label='GameUI_GameMenu_NewGame',command='OpenCreateMultiplayerGameDialog',OnlyInGame='1') # d.blocks.append(b) # добавляем в список блоков документа d.blocks.append(b2) # добавляет следующий блок в конец списка # print(d) print("===============================") # b3 = Block(label='Конфиг с.cfg',command='engine exec c.cfg') d.blocks.insert(0,b3) # вставляет новый блок в начало списка # print(d) print("===============================") # d.blocks.insert(1,d.blocks.pop(0)) #перемещает с первого места на второе print("===============================") # print(d)
"GameMenu" { } =============================== "GameMenu" { "1" { "label" "GameUI_GameMenu_Disconnect" "command" "Disconnect" } "2" { "label" "GameUI_GameMenu_NewGame" "command" "OpenCreateMultiplayerGameDialog" "OnlyInGame" "1" } } =============================== "GameMenu" { "1" { "label" "Конфиг с.cfg" "command" "engine exec c.cfg" } "2" { "label" "GameUI_GameMenu_Disconnect" "command" "Disconnect" } "3" { "label" "GameUI_GameMenu_NewGame" "command" "OpenCreateMultiplayerGameDialog" "OnlyInGame" "1" } } =============================== =============================== "GameMenu" { "1" { "label" "GameUI_GameMenu_Disconnect" "command" "Disconnect" } "2" { "label" "Конфиг с.cfg" "command" "engine exec c.cfg" } "3" { "label" "GameUI_GameMenu_NewGame" "command" "OpenCreateMultiplayerGameDialog" "OnlyInGame" "1" } } Process finished with exit code 0
Отредактировано xam1816 (Ноя. 30, 2021 21:52:34)
Офлайн