translators-will commited on
Commit
26e8fd1
·
verified ·
1 Parent(s): 33e740a

Adding app file

Browse files
Files changed (1) hide show
  1. app.py +271 -0
app.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio UI
2
+ import re
3
+ import gradio as gr
4
+ import tempfile
5
+ import os
6
+ from openai import OpenAI
7
+ from dotenv import load_dotenv
8
+ import subprocess
9
+ import shutil
10
+ from timeit import default_timer as timer
11
+
12
+ # Load environment variables
13
+
14
+ load_dotenv()
15
+ os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')
16
+ OPENAI_MODEL = "gpt-4o-mini"
17
+
18
+ # TranslateCode and ExecuteCode class implementations
19
+
20
+ class TranslateCode:
21
+ def __init__(self, openai_client, model):
22
+ self.openai = openai_client
23
+ self.model = model
24
+
25
+ def user_prompt_for(self, python, lang_select):
26
+ user_prompt = f"Rewrite this Python code in {lang_select} with the fastest possible implementation that produces identical output in the least time. "
27
+ user_prompt += f"Respond only with {lang_select} code; do not explain your work; only return {lang_select} code. "
28
+ user_prompt += "Pay attention to number types to ensure no int overflows. Remember to include all necessary dependencies and libraries.\n\n"
29
+ user_prompt += "If translating to Rust, make sure to include the necessary packages and crates."
30
+ user_prompt += python
31
+ return user_prompt
32
+
33
+ def messages_for(self, python, lang_select):
34
+ # System message for OpenAI API
35
+ system_message = "You are an assistant that reimplements Python code in high performance code for a Windows PC. "
36
+ system_message += "Respond only with code; do not provide any explanations. "
37
+ system_message += "The response needs to produce an identical output in the fastest possible time."
38
+
39
+ return [
40
+ {"role": "system", "content": system_message},
41
+ {"role": "user", "content": self.user_prompt_for(python, lang_select)}
42
+ ]
43
+
44
+ def translate_code(self, code_file, lang_select):
45
+ stream = self.openai.chat.completions.create(model=self.model, messages=self.messages_for(code_file, lang_select), stream=True)
46
+ code = ""
47
+ for chunk in stream:
48
+ fragment = chunk.choices[0].delta.content or ""
49
+ code += fragment
50
+ pattern = r"```(c|cpp|rust|javascript)\n"
51
+ code = re.sub(pattern, "", code).replace("```", "")
52
+ return code
53
+
54
+
55
+ class ExecuteCode:
56
+ def __init__(self, translator):
57
+ self.translator = translator
58
+
59
+ def extract_dependencies(self, code):
60
+ try:
61
+ dependency_pattern = r"""
62
+ (?:use\s+(?!std::)[a-zA-Z_][a-zA-Z0-9_]*::|extern\s+crate\s+(?!std)[a-zA-Z_][a-zA-Z0-9_]*);?
63
+ |
64
+ \#include\s*<([a-zA-Z_][a-zA-Z0-9_/.]*)>
65
+ |
66
+ (?:import\s+.*\s+from\s+['"]([a-zA-Z_][a-zA-Z0-9_/.]*)['"]
67
+ |require\s*\(\s*['"]([a-zA-Z_][a-zA-Z0-9_/.]*)['"]\s*\))
68
+ """
69
+ matches = re.findall(dependency_pattern, code, re.VERBOSE)
70
+ dependencies = [match for match in matches if any(match)]
71
+ return dependencies if matches else []
72
+ except re.error as e:
73
+ raise ValueError(f"Regex error while extracting dependencies: {e}")
74
+
75
+ def execute_code(self, code_file, lang_select):
76
+ if lang_select == "Rust":
77
+ rust_code = self.translator.translate_code(code_file, lang_select)
78
+ try:
79
+ dependencies = self.extract_dependencies(rust_code)
80
+ temp_dir = tempfile.mkdtemp()
81
+ src_dir = os.path.join(temp_dir, "src")
82
+ os.makedirs(src_dir, exist_ok=True)
83
+ cargo_toml = f"""
84
+ [package]
85
+ name = "temp_project"
86
+ version = "0.1.0"
87
+ edition = "2021"
88
+
89
+ [dependencies]
90
+ """
91
+ for dependency in dependencies:
92
+ crate = dependency[0]
93
+ cargo_toml += f"{crate} = \"*\"\n"
94
+ with open(os.path.join(temp_dir, "Cargo.toml"), "w") as f:
95
+ f.write(cargo_toml)
96
+ main_rs_path = os.path.join(src_dir, "main.rs")
97
+ with open(main_rs_path, "w", encoding="utf-8") as f:
98
+ f.write(rust_code)
99
+ cargo_build = subprocess.run(["cargo", "build", "--release"],
100
+ cwd=temp_dir,
101
+ stdout=subprocess.PIPE,
102
+ stderr=subprocess.PIPE,
103
+ text=True)
104
+ if cargo_build.returncode != 0:
105
+ return f"Cargo build failed:\n{cargo_build.stderr}", 0
106
+ executable_path = os.path.join(temp_dir, "target", "release", "temp_project")
107
+ start_time = timer()
108
+ run_result = subprocess.run([executable_path],
109
+ stdout=subprocess.PIPE,
110
+ stderr=subprocess.PIPE,
111
+ text=True)
112
+ end_time = timer()
113
+ execution_time = end_time - start_time
114
+ if run_result.returncode != 0:
115
+ print(f"Execution failed: {run_result.stderr}")
116
+ return run_result.stdout, execution_time
117
+ finally:
118
+ if temp_dir:
119
+ shutil.rmtree(temp_dir, ignore_errors=True)
120
+ elif lang_select in ["C", "C++"]:
121
+ code = self.translator.translate_code(code_file, lang_select)
122
+ with tempfile.TemporaryDirectory() as temp_dir:
123
+ file_extension = "c" if lang_select == "C" else "cpp"
124
+ file_path = os.path.join(temp_dir, f"translated_code.{file_extension}")
125
+ with open(file_path, "w") as f:
126
+ f.write(code)
127
+ executable_path = os.path.join(temp_dir, "translated_code")
128
+ compiler = "gcc" if lang_select == "C" else "g++"
129
+ compile_result = subprocess.run([compiler, file_path, "-o", executable_path],
130
+ stdout=subprocess.PIPE,
131
+ stderr=subprocess.PIPE,
132
+ text=True)
133
+ if compile_result.returncode != 0:
134
+ return f"Compilation failed:\n{compile_result.stderr}", 0
135
+ start_time = timer()
136
+ run_result = subprocess.run([executable_path],
137
+ stdout=subprocess.PIPE,
138
+ stderr=subprocess.PIPE,
139
+ text=True)
140
+ end_time = timer()
141
+ execution_time = end_time - start_time
142
+ return run_result.stdout, execution_time
143
+ elif lang_select == "Javascript":
144
+ js_code = self.translator.translate_code(code_file, lang_select)
145
+ with tempfile.NamedTemporaryFile(suffix='.js', delete=False) as js_file:
146
+ js_file.write(js_code.encode("utf-8"))
147
+ js_file.flush()
148
+ js_file_path = js_file.name
149
+ try:
150
+ start_time = timer()
151
+ run_result = subprocess.run(["node", js_file_path],
152
+ stdout=subprocess.PIPE,
153
+ stderr=subprocess.PIPE,
154
+ text=True)
155
+ end_time = timer()
156
+ execution_time = end_time - start_time
157
+ return run_result.stdout, execution_time
158
+ finally:
159
+ os.remove(js_file_path)
160
+ else:
161
+ return "Language not supported", 0
162
+
163
+
164
+ def process_code(python_code: str, target_language: str):
165
+ """Process the uploaded Python code and return both original and translated outputs"""
166
+ # Initialize components
167
+ openai_client = OpenAI()
168
+ translator = TranslateCode(openai_client, OPENAI_MODEL)
169
+ executor = ExecuteCode(translator)
170
+
171
+ # Run Python code
172
+ python_output = ""
173
+ python_time = 0
174
+ try:
175
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as temp_py_file:
176
+ temp_py_file.write(python_code.encode('utf-8'))
177
+ temp_py_file_path = temp_py_file.name
178
+
179
+ start_time = timer()
180
+ result = subprocess.run(["python", temp_py_file_path],
181
+ capture_output=True,
182
+ text=True)
183
+ end_time = timer()
184
+
185
+ python_output = result.stdout if result.returncode == 0 else result.stderr
186
+ python_time = end_time - start_time
187
+ except Exception as e:
188
+ python_output = str(e)
189
+ finally:
190
+ if 'temp_py_file_path' in locals() and os.path.exists(temp_py_file_path):
191
+ os.remove(temp_py_file_path)
192
+
193
+ # Translate and run the code
194
+ translated_code = translator.translate_code(python_code, target_language)
195
+ translated_output, translated_time = executor.execute_code(translated_code, target_language)
196
+
197
+ # Format the outputs
198
+ python_output = python_output.replace("Â", "")
199
+ translated_output = translated_output.replace("Â", "")
200
+ python_result = f"Output:\n{python_output}\nExecution time: {python_time:.4f} seconds"
201
+ translated_result = f"Output:\n{translated_output}\nExecution time: {translated_time:.4f} seconds"
202
+
203
+ return python_code, translated_code, python_result, translated_result
204
+
205
+ def create_gradio_interface():
206
+ with gr.Blocks(title="SyntaxShift: Code Translator") as interface:
207
+ gr.Markdown("# SyntaxShift: Code Translator")
208
+ gr.Markdown("It's like Google Translate, but for code. Upload a Python file or paste Python code to translate it to C, C++, Rust, or Javascript, and run the code.")
209
+
210
+ with gr.Row():
211
+ with gr.Column():
212
+ python_code = gr.Code(
213
+ label="Python Code",
214
+ language="python",
215
+ lines=20
216
+ )
217
+ target_language = gr.Dropdown(
218
+ choices=["C", "C++", "Rust", "Javascript"],
219
+ label="Target Language",
220
+ value="C"
221
+ )
222
+ translate_button = gr.Button("Translate and Run")
223
+
224
+ with gr.Row():
225
+ with gr.Column():
226
+ translated_code = gr.Code(
227
+ label="Translated Code",
228
+ language="python", # This will update dynamically
229
+ lines=20
230
+ )
231
+
232
+ with gr.Row():
233
+ with gr.Column():
234
+ python_output = gr.Textbox(
235
+ label="Python Execution Result",
236
+ lines=5
237
+ )
238
+ with gr.Column():
239
+ translated_output = gr.Textbox(
240
+ label="Translated Code Execution Result",
241
+ lines=5
242
+ )
243
+
244
+ # Update language display based on selection
245
+ def update_language(lang):
246
+ lang_map = {
247
+ "C": "c",
248
+ "C++": "cpp",
249
+ "Rust": "rust",
250
+ "Javascript": "javascript"
251
+ }
252
+ return gr.Code.update(language=lang_map[lang])
253
+
254
+ target_language.change(
255
+ fn=update_language,
256
+ inputs=[target_language],
257
+ outputs=[translated_code]
258
+ )
259
+
260
+ # Main translation and execution flow
261
+ translate_button.click(
262
+ fn=process_code,
263
+ inputs=[python_code, target_language],
264
+ outputs=[python_code, translated_code, python_output, translated_output]
265
+ )
266
+
267
+ return interface
268
+
269
+ if __name__ == "__main__":
270
+ demo = create_gradio_interface()
271
+ demo.launch(share=True)