mirror of https://github.com/corca-ai/EVAL
parent
cca84704ff
commit
65c0c6de80
@ -0,0 +1,3 @@
|
||||
from .patch import CodePatcher
|
||||
from .read import CodeReader
|
||||
from .write import CodeWriter
|
@ -0,0 +1,179 @@
|
||||
"""
|
||||
patch protocol:
|
||||
|
||||
<filepath>|<line>,<col>|<line>,<col>|<content>
|
||||
---~~~+++===+++~~~---
|
||||
<filepath>|<line>,<col>|<line>,<col>|<content>
|
||||
---~~~+++===+++~~~---
|
||||
...
|
||||
---~~~+++===+++~~~---
|
||||
|
||||
let say original code is:
|
||||
```
|
||||
import requests
|
||||
|
||||
def crawl_news(keyword):
|
||||
url = f"https://www.google.com/search?q={keyword}+news"
|
||||
response = requests.get(url)
|
||||
|
||||
news = []
|
||||
for result in response:
|
||||
news.append(result.text)
|
||||
|
||||
return news
|
||||
```
|
||||
|
||||
and we want to change it to:
|
||||
```
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
def crawl_news(keyword):
|
||||
url = f"https://www.google.com/search?q={keyword}+news"
|
||||
html = requests.get(url).text
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
news_results = soup.find_all("div", class_="BNeawe vvjwJb AP7Wnd")
|
||||
|
||||
news_titles = []
|
||||
for result in news_results:
|
||||
news_titles.append(result.text)
|
||||
|
||||
return news_titles
|
||||
```
|
||||
|
||||
then the command will be:
|
||||
test.py|2,1|2,1|from bs4 import BeautifulSoup
|
||||
|
||||
---~~~+++===+++~~~---
|
||||
test.py|5,5|5,33|html = requests.get(url).text
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
news_results = soup.find_all("div", class_="BNeawe vvjwJb AP7Wnd")
|
||||
---~~~+++===+++~~~---
|
||||
test.py|7,5|9,13|news_titles = []
|
||||
for result in news_results:
|
||||
news_titles
|
||||
---~~~+++===+++~~~---
|
||||
test.py|11,16|11,16|_titles
|
||||
"""
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
class Position:
|
||||
separator = ","
|
||||
|
||||
def __init__(self, line: int, col: int):
|
||||
self.line: int = line
|
||||
self.col: int = col
|
||||
|
||||
@staticmethod
|
||||
def from_str(pos: str) -> "Position":
|
||||
line, col = pos.split(Position.separator)
|
||||
return Position(int(line) - 1, int(col) - 1)
|
||||
|
||||
|
||||
class PatchCommand:
|
||||
separator = "|"
|
||||
|
||||
def __init__(self, filepath: str, start: Position, end: Position, content: str):
|
||||
self.filepath: str = filepath
|
||||
self.start: Position = start
|
||||
self.end: Position = end
|
||||
self.content: str = content
|
||||
|
||||
def read_lines(self) -> list[str]:
|
||||
with open(self.filepath, "r") as f:
|
||||
lines = f.readlines()
|
||||
return lines
|
||||
|
||||
def write_lines(self, lines: list[str]) -> int:
|
||||
with open(self.filepath, "w") as f:
|
||||
f.writelines(lines)
|
||||
return sum([len(line) for line in lines])
|
||||
|
||||
def execute(self) -> Tuple[int, int]:
|
||||
lines = self.read_lines()
|
||||
before = sum([len(line) for line in lines])
|
||||
|
||||
lines[self.start.line] = (
|
||||
lines[self.start.line][: self.start.col]
|
||||
+ self.content
|
||||
+ lines[self.end.line][self.end.col :]
|
||||
)
|
||||
lines = lines[: self.start.line + 1] + lines[self.end.line + 1 :]
|
||||
|
||||
after = self.write_lines(lines)
|
||||
|
||||
written = len(self.content)
|
||||
deleted = before - after + written
|
||||
|
||||
return written, deleted
|
||||
|
||||
@staticmethod
|
||||
def from_str(command: str) -> "PatchCommand":
|
||||
filepath, start, end = command.split(PatchCommand.separator)[:3]
|
||||
content = command[len(filepath + start + end) + 3 :]
|
||||
return PatchCommand(
|
||||
filepath, Position.from_str(start), Position.from_str(end), content
|
||||
)
|
||||
|
||||
|
||||
class CodePatcher:
|
||||
separator = "\n---~~~+++===+++~~~---\n"
|
||||
|
||||
@staticmethod
|
||||
def sort_commands(commands: list[PatchCommand]) -> list[PatchCommand]:
|
||||
return sorted(commands, key=lambda c: c.start.line, reverse=True)
|
||||
|
||||
@staticmethod
|
||||
def patch(bulk_command: str) -> Tuple[int, int]:
|
||||
commands = [
|
||||
PatchCommand.from_str(command)
|
||||
for command in bulk_command.split(CodePatcher.separator)
|
||||
if command != ""
|
||||
]
|
||||
commands = CodePatcher.sort_commands(commands)
|
||||
|
||||
written, deleted = 0, 0
|
||||
for command in commands:
|
||||
if command:
|
||||
w, d = command.execute()
|
||||
written += w
|
||||
deleted += d
|
||||
return written, deleted
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
commands = """test.py|2,1|2,1|from bs4 import BeautifulSoup
|
||||
|
||||
---~~~+++===+++~~~---
|
||||
test.py|5,5|5,33|html = requests.get(url).text
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
news_results = soup.find_all("div", class_="BNeawe vvjwJb AP7Wnd")
|
||||
---~~~+++===+++~~~---
|
||||
test.py|7,5|9,13|news_titles = []
|
||||
for result in news_results:
|
||||
news_titles
|
||||
---~~~+++===+++~~~---
|
||||
test.py|11,16|11,16|_titles
|
||||
"""
|
||||
|
||||
example = """import requests
|
||||
|
||||
def crawl_news(keyword):
|
||||
url = f"https://www.google.com/search?q={keyword}+news"
|
||||
response = requests.get(url)
|
||||
|
||||
news = []
|
||||
for result in response:
|
||||
news.append(result.text)
|
||||
|
||||
return news
|
||||
"""
|
||||
testfile = "test.py"
|
||||
with open(testfile, "w") as f:
|
||||
f.write(example)
|
||||
|
||||
patcher = CodePatcher()
|
||||
written, deleted = patcher.patch(commands)
|
||||
print(f"written: {written}, deleted: {deleted}")
|
@ -0,0 +1,35 @@
|
||||
"""
|
||||
read protocol:
|
||||
|
||||
<filepath>|<start line>-<end line>
|
||||
"""
|
||||
|
||||
|
||||
class ReadCommand:
|
||||
separator = "|"
|
||||
|
||||
def __init__(self, filepath: str, start: int, end: int):
|
||||
self.filepath: str = filepath
|
||||
self.start: int = start
|
||||
self.end: int = end
|
||||
|
||||
def execute(self):
|
||||
with open(self.filepath, "r") as f:
|
||||
code = f.readlines()
|
||||
if self.start == self.end:
|
||||
code = code[self.start - 1]
|
||||
else:
|
||||
code = "".join(code[self.start - 1 : self.end])
|
||||
return code
|
||||
|
||||
@staticmethod
|
||||
def from_str(command: str) -> "ReadCommand":
|
||||
filepath, line = command.split(ReadCommand.separator)
|
||||
start, end = line.split("-")
|
||||
return ReadCommand(filepath, int(start), int(end))
|
||||
|
||||
|
||||
class CodeReader:
|
||||
@staticmethod
|
||||
def read(command: str) -> str:
|
||||
return ReadCommand.from_str(command).execute()
|
@ -0,0 +1,39 @@
|
||||
"""
|
||||
write protocol:
|
||||
|
||||
<filepath>
|
||||
<content>
|
||||
"""
|
||||
|
||||
|
||||
class WriteCommand:
|
||||
separator = "\n"
|
||||
|
||||
def __init__(self, filepath: str, content: int):
|
||||
self.filepath: str = filepath
|
||||
self.content: str = content
|
||||
self.mode: str = "w"
|
||||
|
||||
def with_mode(self, mode: str) -> "WriteCommand":
|
||||
self.mode = mode
|
||||
return self
|
||||
|
||||
def execute(self) -> str:
|
||||
with open(self.filepath, self.mode) as f:
|
||||
f.write(self.content)
|
||||
return self.content
|
||||
|
||||
@staticmethod
|
||||
def from_str(command: str) -> "WriteCommand":
|
||||
filepath = command.split(WriteCommand.separator)[0]
|
||||
return WriteCommand(filepath, command[len(filepath) + 1 :])
|
||||
|
||||
|
||||
class CodeWriter:
|
||||
@staticmethod
|
||||
def write(command: str) -> str:
|
||||
return WriteCommand.from_str(command).with_mode("w").execute()
|
||||
|
||||
@staticmethod
|
||||
def append(command: str) -> str:
|
||||
return WriteCommand.from_str(command).with_mode("a").execute()
|
Loading…
Reference in New Issue