Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
enginestein authored Mar 16, 2024
1 parent da536d0 commit dd793f0
Show file tree
Hide file tree
Showing 25 changed files with 333 additions and 39 deletions.
67 changes: 33 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Baker

[![Downloads](https://static.pepy.tech/badge/baker-python)](https://pepy.tech/project/baker-python)

*Bot-Maker* Baker! Is a framework to create chatbots with Python in the easiest and simplest route, train your chatbot by texting or adding data in XML, JSON or YAML files.

# Installation
Expand Down Expand Up @@ -72,9 +70,11 @@ The files can also be empty for example a JSON file can be like this:
To train the chatbot, use the `Trainer` class. Here is an example of basic training:

```py
from baker import trainer
import baker.trainer
import baker.bparser
import baker.chatbot

bot = trainer.Trainer('database.yaml')
bot = baker.trainer.Trainer('data.json')

user_input = input("You: ")
response = bot.get_response(user_input)
Expand All @@ -91,7 +91,9 @@ from this route the keyword (user's question) must be already created in the fil
But with this way to train you can train the chatbot as long you want to with custom keywords (no need to define them in the data file) and their infinite responses:

```py
trainer = Trainer("database.json")
import baker.trainer

trainer = baker.trainer.Trainer('data.json')
trainer.loop_training()
```

Expand All @@ -102,7 +104,7 @@ The data file can either be empty or it can have keywords, pre-defined keyowrds
To parse the chatbot to run and test it use the `Parser` class:

```py
from baker import parser
import baker.bparser

def test_chatbot(bot):
while True:
Expand All @@ -113,63 +115,60 @@ def test_chatbot(bot):
response = bot.get_response(user_input)
print("Bot:", response)

bot = parser.Parser('database.json')
bot = baker.bparser.Parser('data.json')

test_chatbot(bot)
```

The above code will run the chatbot, but there is anther simpler way to run the chatbot with it's specified name which is to use the `Chatbot` class:

```py
from baker import trainer
from baker import parser
from baker import chatbot

trainer = trainer.Trainer('database.json')
parser = parser.Parser('database.json')
my_chatbot = chatbot.Chatbot("MyChatbot")
my_chatbot.interactive_session(trainer, parser)
import baker.trainer
import baker.bparser
import baker.chatbot

trainer = baker.trainer.Trainer('data.json')
parser = baker.bparser.Parser('data.json')
my_chatbot = baker.chatbot.Chatbot("MyChatbot")
my_chatbot.session(trainer, parser)
```

`Parser` class has more functions regarding the data file:

- Exporting responses :

```py
response_file_name = "responses.json"
Parser = Parser(response_file_name)
parser.export_responses("exported_responses.xml")
import baker.bparser

response_file_name = "data.json"
parser_instance = baker.bparser.Parser(response_file_name)
parser_instance.export_responses(export_file_name="data2.json")
```

- Reset resposes

```py
parser.reset_responses("A_User_Question")
baker.bparser.Parser.reset_responses("A_User_Question")
```

- Removing responses:

```py
user_input = "What is the weather like?"
response_to_remove = "I'm not sure."
parser.remove_response(user_input, response_to_remove)
```
parser_instance2 = baker.bparser.Parser("data.json")

- List questions:

```py
key_questions = parser.list_questions()
print("List of Key Questions:")
for question in key_questions:
print(question)
user_input = "Hello"
response_to_remove = "Heyy"
parser_instance2.remove_response(user_input, response_to_remove)
```

- Count responses:

```py
user_input = "Tell me a joke"
response_count = parser.count_responses(user_input)
print(f"Number of Responses for '{user_input}': {response_count}")
parser_instance3 = baker.bparser.Parser("data.json")
user_input = "Hello"

count = parser_instance3.count_responses(user_input)
print(f"Number of Responses for '{user_input}': {count}")
```

Keep training your chatbot by texting or adding words in the database and then run it!
Keep training your chatbot by texting or adding words in the database and then run it!
8 changes: 8 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from baker import bparser
from baker import chatbot
from baker import trainer
from tests import test_chatbot
from tests import test_functions
from tests import test_loop_trainer
from tests import test_parser
from tests import test_trainer
Binary file added baker/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added baker/__pycache__/bparser.cpython-312.pyc
Binary file not shown.
Binary file added baker/__pycache__/chatbot.cpython-312.pyc
Binary file not shown.
Binary file added baker/__pycache__/trainer.cpython-312.pyc
Binary file not shown.
97 changes: 97 additions & 0 deletions baker/bparser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import json
import random
import os
import yaml
import xml.etree.ElementTree as ET

class Parser:
def __init__(self, response_file_name):
self.file_path = response_file_name
self.responses = self.load_responses(self.file_path)

def load_responses(self, file_path):
_, file_extension = os.path.splitext(file_path)
with open(file_path, 'r') as file:
if file_extension == '.json':
responses = json.load(file)
elif file_extension == '.yaml' or file_extension == '.yml':
responses = yaml.safe_load(file)
elif file_extension == '.xml':
root = ET.parse(file).getroot()
responses = {}
for item in root:
key = item.tag
value = [child.text for child in item]
responses[key] = value
else:
raise ValueError(f"Unsupported file format: {file_extension}")
return responses

def save_responses(self):
_, file_extension = os.path.splitext(self.file_path)
with open(self.file_path, 'w') as file:
if file_extension == '.json':
json.dump(self.responses, file, indent=4)
elif file_extension == '.yaml' or file_extension == '.yml':
yaml.dump(self.responses, file, default_flow_style=False)
elif file_extension == '.xml':
root = ET.Element('responses')
for key, values in self.responses.items():
item = ET.SubElement(root, key)
for value in values:
ET.SubElement(item, 'response').text = value
tree = ET.ElementTree(root)
tree.write(file, encoding="utf-8", xml_declaration=True)
else:
raise ValueError(f"Unsupported file format: {file_extension}")

def train_response(self, user_input, new_response):
if user_input in self.responses:
self.responses[user_input].append(new_response)
else:
self.responses[user_input] = [new_response]
self.save_responses()

def get_response(self, user_input):
if user_input in self.responses:
return random.choice(self.responses[user_input])
else:
return "I'm not sure how to respond to that."

def remove_response(self, user_input, response):
if user_input in self.responses and response in self.responses[user_input]:
self.responses[user_input].remove(response)
self.save_responses()

def list_key_questions(self):
return list(self.responses.keys())

def count_responses(self, user_input):
if user_input in self.responses:
return len(self.responses[user_input])
else:
return 0

def reset_responses(self, user_input):
if user_input in self.responses:
self.responses[user_input] = []
self.save_responses()

def export_responses(self, export_file_name):
export_extension = os.path.splitext(export_file_name)[1]

with open(export_file_name, 'w') as export_file:
if export_extension == '.json':
json.dump(self.responses, export_file, indent=4)
elif export_extension == '.yaml' or export_extension == '.yml':
yaml.dump(self.responses, export_file, default_flow_style=False)
elif export_extension == '.xml':
root = ET.Element('responses')
for key, values in self.responses.items():
item = ET.SubElement(root, key)
for value in values:
ET.SubElement(item, 'response').text = value
tree = ET.ElementTree(root)
tree.write(export_file, encoding="utf-8", xml_declaration=True)
else:
raise ValueError(f"Unsupported export file format: {export_extension}")
8 changes: 4 additions & 4 deletions baker/chatbot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
from parser import Parser
from trainer import Trainer
import baker.trainer
import baker.bparser as bparser

class Chatbot:
def __init__(self, name):
Expand All @@ -13,5 +13,5 @@ def session(self, trainer, parser):
if user_input.lower() == "exit":
print("Session ended.")
break
response = parser.get_response(user_input)
print("Bot:", response)
response = parser.get_response(user_input) # Corrected line
print("Bot:", response)
74 changes: 74 additions & 0 deletions demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#test-chatbot.py

import baker.trainer
import baker.bparser
import baker.chatbot

trainer = baker.trainer.Trainer('data.json')
parser = baker.bparser.Parser('data.json')
my_chatbot = baker.chatbot.Chatbot("MyChatbot")
my_chatbot.session(trainer, parser)

#test-functions.py

import baker.bparser

response_file_name = "data.json"
parser_instance = baker.bparser.Parser(response_file_name)
parser_instance.export_responses(export_file_name="data2.json")

baker.bparser.Parser.reset_responses("A_User_Question")


parser_instance2 = baker.bparser.Parser("data.json")

user_input = "Hello"
response_to_remove = "Heyy"
parser_instance2.remove_response(user_input, response_to_remove)

parser_instance3 = baker.bparser.Parser("data.json")
user_input = "Hello"

count = parser_instance3.count_responses(user_input)
print(f"Number of Responses for '{user_input}': {count}")

#test-loop-trainer.py

import baker.trainer

trainer = baker.trainer.Trainer('data.json')
trainer.loop_training()

#test-parser.py

import baker.bparser

def test_chatbot(bot):
while True:
user_input = input("You: ")
if user_input.lower() == "exit":
print("Testing session ended.")
break
response = bot.get_response(user_input)
print("Bot:", response)

bot = baker.bparser.Parser('data.json')

test_chatbot(bot)

#test-trainer.py

import baker.trainer
import baker.bparser
import baker.chatbot

bot = baker.trainer.Trainer('data.json')

user_input = input("You: ")
response = bot.get_response(user_input)
print("Bot:", response)

# Train the bot with a new response
new_response = input("New response: ")
bot.train_response(user_input, new_response)
print("Bot has been trained with the new response!")
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name='baker-python',
version='1.1',
version='2.0',
packages=['baker'],
url='https://github.com/enginestein/Baker',
license='GPL-3.0-only',
Expand Down
16 changes: 16 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import unittest

import tests.test_chatbot
import tests.test_functions
import tests.test_loop_trainer
import tests.test_parser
import tests.test_trainer

if __name__ == "__main__":
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(tests.test_chatbot.TestChatbot))
#test_suite.addTest(unittest.makeSuite(tests.test_functions.TestFunctions))
#test_suite.addTest(unittest.makeSuite(tests.test_loop_trainer.TestLoopTrainer))
#test_suite.addTest(unittest.makeSuite(tests.test_parser.TestParser))
#test_suite.addTest(unittest.makeSuite(tests.test_trainer.TestTrainer))
unittest.TextTestRunner().run(test_suite)
Empty file added tests/__init__.py
Empty file.
Binary file added tests/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_chatbot.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_functions.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_loop_trainer.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_parser.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_trainer.cpython-312.pyc
Binary file not shown.
3 changes: 3 additions & 0 deletions tests/data-empty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{

}
14 changes: 14 additions & 0 deletions tests/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Hello": [
"Hi",
"Hello",
"Hey mister, how are you?"
],
"How are you": [
"I'm good sir what about you? "
],
"I am good too": [
"that is good to know! ",
"that is very good to know! "
]
}
Loading

0 comments on commit dd793f0

Please sign in to comment.