├── .gitignore ├── LICENSE ├── README.md ├── langgraph.py ├── openai-agent.py ├── python-coding-agent.py ├── requirements.txt └── temp.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 110 | .pdm.toml 111 | .pdm-python 112 | .pdm-build/ 113 | 114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 115 | __pypackages__/ 116 | 117 | # Celery stuff 118 | celerybeat-schedule 119 | celerybeat.pid 120 | 121 | # SageMath parsed files 122 | *.sage.py 123 | 124 | # Environments 125 | .env 126 | .venv 127 | env/ 128 | venv/ 129 | ENV/ 130 | env.bak/ 131 | venv.bak/ 132 | 133 | # Spyder project settings 134 | .spyderproject 135 | .spyproject 136 | 137 | # Rope project settings 138 | .ropeproject 139 | 140 | # mkdocs documentation 141 | /site 142 | 143 | # mypy 144 | .mypy_cache/ 145 | .dmypy.json 146 | dmypy.json 147 | 148 | # Pyre type checker 149 | .pyre/ 150 | 151 | # pytype static type analyzer 152 | .pytype/ 153 | 154 | # Cython debug symbols 155 | cython_debug/ 156 | 157 | # PyCharm 158 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 159 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 160 | # and can be added to the global gitignore or merged into this file. For a more nuclear 161 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 162 | #.idea/ 163 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Meruvu Likith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Python Coding Agent 4 | 5 | A versatile Python agent utilizing OpenAI's GPT-3.5 to assist with various coding tasks, from generating code snippets to providing debugging help. This project aims to streamline the coding process by leveraging AI for enhanced productivity and learning. 6 | 7 | ## Table of Contents 8 | 9 | - [Features](#features) 10 | - [Installation](#installation) 11 | - [Usage](#usage) 12 | - [File Descriptions](#file-descriptions) 13 | - [License](#license) 14 | - [Contact](#contact) 15 | 16 | ## Features 17 | 18 | - **Code Generation:** Generate code snippets based on natural language prompts. 19 | - **Debugging Assistance:** Get help with debugging Python code. 20 | - **Code Explanation:** Understand complex code with detailed explanations. 21 | - **Interactive Sessions:** Engage in interactive coding sessions with the agent. 22 | 23 | ## Installation 24 | 25 | 1. **Clone the Repository:** 26 | ```bash 27 | git clone https://github.com/LikithMeruvu/Python-coding-Agent.git 28 | cd Python-coding-Agent 29 | ``` 30 | 31 | 2. **Create and activate a virtual environment:** 32 | ```bash 33 | python -m venv venv 34 | source venv/bin/activate # On Windows use `venv\Scripts\activate` 35 | ``` 36 | 37 | 3. **Install Dependencies:** 38 | ```bash 39 | pip install -r requirements.txt 40 | ``` 41 | 42 | ## Usage 43 | 44 | Open Respective Files and Add you API info in Variables specified by 'your_api' 45 | 46 | 1. **Run the Agent with GroqAPI:** 47 | ```bash 48 | python python-coding-agent.py 49 | ``` 50 | 51 | **Run the Agent with OPENAI_API:** 52 | ```bash 53 | python openai-agent.py 54 | ``` 55 | 56 | 1. **Interact with the Agent:** 57 | - The agent will prompt you for input. Provide your coding queries, and the agent will respond accordingly. 58 | 59 | ## File Descriptions 60 | 61 | - **langgraph.py:** Contains the logic for the agents in langgraph. 62 | - **openai-agent.py:** Manages interactions with the OpenAI API. 63 | - **python-coding-agent.py:** Core functionality of the Python coding agent. 64 | - **temp.py:** Temporary file for testing and experimentation. 65 | - **requirements.txt:** Lists all the dependencies required to run the project. 66 | - **README.md:** Provides an overview and usage instructions for the project. 67 | - **LICENSE:** License information for the project. 68 | 69 | 70 | ## License 71 | 72 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. 73 | 74 | ## Contact 75 | 76 | For any questions or suggestions, please open an issue or reach out to the maintainer: 77 | 78 | - GitHub: [LikithMeruvu](https://github.com/LikithMeruvu) 79 | 80 | -------------------------------------------------------------------------------- /langgraph.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from langchain_groq import ChatGroq 4 | from langchain_core.prompts import ChatPromptTemplate 5 | from langchain_core.pydantic_v1 import BaseModel, Field 6 | from langgraph.graph.message import AnyMessage, add_messages 7 | from langgraph.graph import END, StateGraph 8 | from langgraph.checkpoint.sqlite import SqliteSaver 9 | from typing import Annotated, Dict, TypedDict, List 10 | from operator import itemgetter 11 | from langchain_core.runnables import RunnablePassthrough 12 | from langchain_core.prompts import PromptTemplate 13 | from IPython.display import Image, display 14 | import uuid 15 | 16 | # Set environment variables 17 | os.environ['TOKENIZERS_PARALLELISM'] = 'true' 18 | # mistral_api_key = os.getenv("MISTRAL_API_KEY") # Ensure this is set 19 | 20 | # Set up the LLM 21 | llm = ChatGroq(temperature=0, groq_api_key="groq_api", model_name="llama3-8b-8192") 22 | 23 | # Define the prompt template 24 | code_gen_prompt_claude = ChatPromptTemplate.from_messages( 25 | [ 26 | ( 27 | "system", 28 | """You are a coding assistant. Ensure any code you provide can be executed with all required imports and variables defined. Structure your answer: 1) a prefix describing the code solution, 2) the imports, 3) the functioning code block. 29 | \n Here is the user question:""", 30 | ), 31 | ("placeholder", "{messages}"), 32 | ] 33 | ) 34 | 35 | # Define the data model 36 | class code(BaseModel): 37 | """Code output""" 38 | 39 | prefix: str = Field(description="Description of the problem and approach") 40 | imports: str = Field(description="Code block import statements") 41 | code: str = Field(description="Code block not including import statements") 42 | description = "Schema for code solutions to questions about LCEL." 43 | 44 | # Set up the structured output 45 | code_gen_chain = llm.with_structured_output(code, include_raw=False) 46 | 47 | # Define the graph state 48 | class GraphState(TypedDict): 49 | """ 50 | Represents the state of our graph. 51 | 52 | Attributes: 53 | error : Binary flag for control flow to indicate whether test error was tripped 54 | messages : With user question, error messages, reasoning 55 | generation : Code solution 56 | iterations : Number of tries 57 | """ 58 | 59 | error: str 60 | messages: Annotated[list[AnyMessage], add_messages] 61 | generation: str 62 | iterations: int 63 | 64 | # Define the nodes 65 | def generate(state: GraphState): 66 | """ 67 | Generate a code solution 68 | 69 | Args: 70 | state (dict): The current graph state 71 | 72 | Returns: 73 | state (dict): New key added to state, generation 74 | """ 75 | 76 | print("---GENERATING CODE SOLUTION---") 77 | 78 | # State 79 | messages = state["messages"] 80 | iterations = state["iterations"] 81 | error = state["error"] 82 | 83 | # Solution 84 | code_solution = code_gen_chain.invoke(messages) 85 | messages += [ 86 | ( 87 | "assistant", 88 | f"Here is my attempt to solve the problem: {code_solution.prefix} \n Imports: {code_solution.imports} \n Code: {code_solution.code}", 89 | ) 90 | ] 91 | 92 | # Increment 93 | iterations = iterations + 1 94 | 95 | # Add delay to reduce API requests 96 | time.sleep(1) # Wait for 1 second 97 | 98 | return {"generation": code_solution, "messages": messages, "iterations": iterations} 99 | 100 | def code_check(state: GraphState): 101 | """ 102 | Check code 103 | 104 | Args: 105 | state (dict): The current graph state 106 | 107 | Returns: 108 | state (dict): New key added to state, error 109 | """ 110 | 111 | print("---CHECKING CODE---") 112 | 113 | # State 114 | messages = state["messages"] 115 | code_solution = state["generation"] 116 | iterations = state["iterations"] 117 | 118 | # Get solution components 119 | prefix = code_solution.prefix 120 | imports = code_solution.imports 121 | code = code_solution.code 122 | 123 | # Check imports 124 | try: 125 | exec(imports) 126 | except Exception as e: 127 | print("---CODE IMPORT CHECK: FAILED---") 128 | error_message = [("user", f"Your solution failed the import test. Here is the error: {e}. Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:")] 129 | messages += error_message 130 | return { 131 | "generation": code_solution, 132 | "messages": messages, 133 | "iterations": iterations, 134 | "error": "yes", 135 | } 136 | 137 | # Check execution 138 | try: 139 | combined_code = f"{imports}\n{code}" 140 | # Use a shared scope for exec 141 | global_scope = {} 142 | exec(combined_code, global_scope) 143 | except Exception as e: 144 | print("---CODE BLOCK CHECK: FAILED---") 145 | error_message = [("user", f"Your solution failed the code execution test: {e}) Reflect on this error and your prior attempt to solve the problem. (1) State what you think went wrong with the prior solution and (2) try to solve this problem again. Return the FULL SOLUTION. Use the code tool to structure the output with a prefix, imports, and code block:")] 146 | messages += error_message 147 | return { 148 | "generation": code_solution, 149 | "messages": messages, 150 | "iterations": iterations, 151 | "error": "yes", 152 | } 153 | 154 | # No errors 155 | print("---NO CODE TEST FAILURES---") 156 | return { 157 | "generation": code_solution, 158 | "messages": messages, 159 | "iterations": iterations, 160 | "error": "no", 161 | } 162 | 163 | def decide_to_finish(state: GraphState): 164 | """ 165 | Determines whether to finish. 166 | 167 | Args: 168 | state (dict): The current graph state 169 | 170 | Returns: 171 | str: Next node to call 172 | """ 173 | error = state["error"] 174 | iterations = state["iterations"] 175 | 176 | if error == "no" or iterations == max_iterations: 177 | print("---DECISION: FINISH---") 178 | return "end" 179 | else: 180 | print("---DECISION: RE-TRY SOLUTION---") 181 | return "generate" 182 | 183 | # Define the graph 184 | builder = StateGraph(GraphState) 185 | 186 | # Add nodes 187 | builder.add_node("generate", generate) # generation solution 188 | builder.add_node("check_code", code_check) # check code 189 | 190 | # Build graph 191 | builder.set_entry_point("generate") 192 | builder.add_edge("generate", "check_code") 193 | builder.add_conditional_edges( 194 | "check_code", 195 | decide_to_finish, 196 | { 197 | "end": END, 198 | "generate": "generate", 199 | }, 200 | ) 201 | 202 | # Compile the graph 203 | memory = SqliteSaver.from_conn_string(":memory:") 204 | graph = builder.compile(checkpointer=memory) 205 | 206 | # Display the graph 207 | try: 208 | display(Image(graph.get_graph(xray=True).draw_mermaid_png())) 209 | except: 210 | pass 211 | 212 | # Run the graph 213 | _printed = set() 214 | thread_id = str(uuid.uuid4()) 215 | config = { 216 | "configurable": { 217 | # Checkpoints are accessed by thread_id 218 | "thread_id": thread_id, 219 | } 220 | } 221 | 222 | # Ask user for input 223 | question = input("Enter your question or search query: ") 224 | 225 | # Run the graph 226 | max_iterations = 5 # Define the maximum number of iterations 227 | events = graph.stream( 228 | {"messages": [("user", question)], "iterations": 0}, config, stream_mode="values" 229 | ) 230 | 231 | def _print_event(event, _printed): 232 | if str(event) not in _printed: 233 | print(event) 234 | _printed.add(str(event)) 235 | 236 | for event in events: 237 | _print_event(event, _printed) 238 | 239 | # Output the final result 240 | print("Final Result:") 241 | print(event['generation']) -------------------------------------------------------------------------------- /openai-agent.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from crewai import Agent, Task, Crew, Process 3 | from langchain.agents import Tool 4 | from langchain_experimental.utilities import PythonREPL 5 | from langchain_community.tools import DuckDuckGoSearchRun 6 | 7 | import os 8 | os.environ["OPENAI_API_KEY"] = "your_key" 9 | 10 | # Create the Python REPL tool 11 | python_repl = PythonREPL() 12 | python_repl_tool = Tool( 13 | name="python_repl", 14 | description="This tool can execute python code and shell commands Use with caution", 15 | func=python_repl.run, 16 | ) 17 | 18 | # Create the DuckDuckGo search tool 19 | duckduckgo_search_tool = Tool( 20 | name="duckduckgo_search", 21 | description="A wrapper around DuckDuckGo Search.", 22 | func=DuckDuckGoSearchRun().run, 23 | ) 24 | 25 | class CustomAgent(Agent): 26 | def __init__(self, *args, **kwargs): 27 | super().__init__(*args, **kwargs) 28 | self.max_attempts = 3 29 | self.attempts = 0 30 | 31 | def run(self, task): 32 | if self.attempts < self.max_attempts: 33 | self.attempts += 1 34 | return super().run(task) 35 | else: 36 | return "Task failed after {} attempts.".format(self.max_attempts) 37 | 38 | coderAgent = CustomAgent( 39 | role='Senior Software engineer and developer', 40 | goal='Write production grade bug free code on this user prompt :- {topic}', 41 | verbose=True, 42 | memory=True, 43 | backstory="You are an experienced developer in big tech companies", 44 | max_iter=5, 45 | max_rpm=2, 46 | tools=[duckduckgo_search_tool], 47 | allow_delegation=True 48 | ) 49 | 50 | DebuggerAgent = CustomAgent( 51 | role='Code Debugger and bug solving agent', 52 | goal='You debug the code line by line and solve bugs and errors in the code by using Python_repl tool', 53 | verbose=True, 54 | memory=True, 55 | backstory="You are a debugger agent with access to a python interpreter", 56 | tools=[duckduckgo_search_tool, python_repl_tool], 57 | max_iter=5, 58 | max_rpm=2, 59 | allow_delegation=True 60 | ) 61 | 62 | coding_task = Task( 63 | description="Write code in this {topic}.", 64 | expected_output='A Bug-free and production-grade code on {topic}', 65 | tools=[duckduckgo_search_tool], 66 | agent=coderAgent, 67 | ) 68 | 69 | debug_task = Task( 70 | description="You should run the python code given by the CoderAgent and Check for bugs and errors", 71 | expected_output='you should communicate to CoderAgent and give feedback on the code if the code got error while execution', 72 | tools=[duckduckgo_search_tool, python_repl_tool], 73 | agent=DebuggerAgent, 74 | output_file='temp.py' 75 | ) 76 | 77 | Final_check = Task( 78 | description="You fill finalize the Code which is verified by debugger agent Which is error free no bugs", 79 | expected_output="You should communicate to DebuggerAgent and if the code is bug free and executed Without errors then return the code to user", 80 | agent=coderAgent, 81 | tools=[duckduckgo_search_tool] 82 | ) 83 | 84 | crew = Crew( 85 | agents=[coderAgent, DebuggerAgent], 86 | tasks=[coding_task, debug_task, Final_check], 87 | process=Process.sequential, 88 | memory=True, 89 | cache=True, 90 | max_rpm=5, 91 | share_crew=True 92 | ) 93 | 94 | while True: 95 | topic = input("Enter the topic: ") 96 | if topic.lower() == 'quit': 97 | break 98 | result = crew.kickoff(inputs={'topic': topic}) 99 | print(result) 100 | -------------------------------------------------------------------------------- /python-coding-agent.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from crewai import Agent, Task, Crew, Process 3 | from langchain.agents import Tool 4 | from langchain_experimental.utilities import PythonREPL 5 | from langchain_community.tools import DuckDuckGoSearchRun 6 | from langchain_groq import ChatGroq 7 | 8 | import os 9 | os.environ["OPENAI_API_KEY"] = "Your_api" 10 | 11 | llm = ChatGroq(temperature=0, groq_api_key="Your_api", model_name="llama3-70b-8192") 12 | 13 | 14 | # Create the Python REPL tool 15 | python_repl = PythonREPL() 16 | python_repl_tool = Tool( 17 | name="python_repl", 18 | description="This tool can execute python code and shell commands (pip commands to modules installation) Use with caution", 19 | func=python_repl.run, 20 | ) 21 | 22 | # Create the DuckDuckGo search tool 23 | duckduckgo_search_tool = Tool( 24 | name="duckduckgo_search", 25 | description="A wrapper around DuckDuckGo Search.", 26 | func=DuckDuckGoSearchRun().run, 27 | ) 28 | 29 | coderAgent = Agent( 30 | role='Senior Software engineer and developer', 31 | goal='Write production grade bug free code on this user prompt :- {topic}', 32 | verbose=True, 33 | memory=True, 34 | backstory="You are an experienced developer in big tech companies", 35 | max_iter=3, 36 | llm = llm, 37 | max_rpm=10, 38 | tools=[duckduckgo_search_tool], 39 | allow_delegation=False 40 | ) 41 | 42 | DebuggerAgent = Agent( 43 | role='Code Debugger and bug solving agent', 44 | goal='You debug the code line by line and solve bugs and errors in the code by using Python_repl tool. You also have Access to search tool which can assist you for searching that bug', 45 | verbose=True, 46 | memory=True, 47 | backstory="You are a debugger agent with access to a python interpreter", 48 | tools=[duckduckgo_search_tool, python_repl_tool], 49 | max_iter=3, 50 | llm = llm, 51 | max_rpm=10, 52 | allow_delegation=True 53 | ) 54 | 55 | coding_task = Task( 56 | description="Write code in this {topic}.", 57 | expected_output='A Bug-free and production-grade code on {topic}', 58 | tools=[duckduckgo_search_tool], 59 | agent=coderAgent, 60 | ) 61 | 62 | debug_task = Task( 63 | description="You should run the python code given by the CoderAgent and Check for bugs and errors", 64 | expected_output='you should communicate to CoderAgent and give feedback on the code if the code got error while execution', 65 | tools=[duckduckgo_search_tool, python_repl_tool], 66 | agent=DebuggerAgent, 67 | output_file='temp.py' 68 | ) 69 | 70 | Final_check = Task( 71 | description="You fill finalize the Code which is verified by debugger agent Which is error free no bugs", 72 | expected_output="You should communicate to DebuggerAgent and if the code is bug free and executed Without errors then return the code to user", 73 | agent=coderAgent, 74 | tools=[duckduckgo_search_tool] 75 | ) 76 | 77 | crew = Crew( 78 | agents=[coderAgent, DebuggerAgent], 79 | tasks=[coding_task, debug_task, Final_check], 80 | process=Process.sequential, 81 | memory=True, 82 | cache=True, 83 | max_rpm=25, 84 | share_crew=True 85 | ) 86 | 87 | while True: 88 | topic = input("Enter the topic: ") 89 | if topic.lower() == 'quit': 90 | break 91 | result = crew.kickoff(inputs={'topic': topic}) 92 | print(result) 93 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | langchain 2 | numpy 3 | pandas 4 | tiktoken 5 | langchain-mistralai 6 | duckduckgo-search 7 | langchain_community 8 | langgraph 9 | Ipython 10 | DDGS -------------------------------------------------------------------------------- /temp.py: -------------------------------------------------------------------------------- 1 | The code has a bug. The error is a NameError("name 'sys' is not defined"). This error occurs because the 'sys' module is not imported. 2 | 3 | The corrected code is: 4 | 5 | ``` 6 | import sys 7 | import heapq 8 | 9 | def dijkstra(graph, start): 10 | distances = {node: sys.maxsize for node in graph} 11 | distances[start] = 0 12 | pq = [(0, start)] 13 | 14 | while pq: 15 | current_distance, current_node = heapq.heappop(pq) 16 | 17 | if current_distance > distances[current_node]: 18 | continue 19 | 20 | for neighbor, weight in graph[current_node].items(): 21 | distance = current_distance + weight 22 | 23 | if distance < distances[neighbor]: 24 | distances[neighbor] = distance 25 | heapq.heappush(pq, (distance, neighbor)) 26 | 27 | return distances 28 | 29 | graph = { 30 | 'A': {'B': 1, 'C': 4}, 31 | 'B': {'A': 1, 'C': 2, 'D': 5}, 32 | 'C': {'A': 4, 'B': 2, 'D': 1}, 33 | 'D': {'B': 5, 'C': 1} 34 | } 35 | 36 | start_node = 'A' 37 | result = dijkstra(graph, start_node) 38 | print(f"Shortest distances from {start_node}: {result}") 39 | ``` 40 | 41 | This code should run without errors and produce the correct output. --------------------------------------------------------------------------------