Skip to content

Commit 8933a9f

Browse files
authored
Add files via upload
1 parent cffd0e7 commit 8933a9f

File tree

7 files changed

+387
-0
lines changed

7 files changed

+387
-0
lines changed

script/order_bot/menu.xlsx

9.44 KB
Binary file not shown.

script/order_bot/order_bot.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# voice process modules
2+
# detect voice
3+
from speech_recognition import Recognizer, Microphone
4+
# generate voice
5+
from pygame import mixer
6+
from tempfile import NamedTemporaryFile
7+
from gtts import gTTS
8+
9+
# time
10+
from datetime import datetime
11+
from time import sleep
12+
13+
# setting
14+
from setting import menu_xlsx_path
15+
16+
# order process modules
17+
# process order
18+
from process_order import load_xlsx, process_data_to_menu, process_price_with_order
19+
20+
class Order_Bot:
21+
def __init__(self, mode = 'voice1'):
22+
# speaker init
23+
mixer.init()
24+
# mode: voice1, voice2, text
25+
self.mode = mode
26+
# recognizer init
27+
self.recognizer = Recognizer()
28+
29+
def line_speaker(self, texts,lang='zh-tw'):
30+
with NamedTemporaryFile(delete=True) as fp:
31+
tts = gTTS(text=texts,lang=lang)
32+
tts.save("{}.mp3".format(fp.name))
33+
mixer.music.load('{}.mp3'.format(fp.name))
34+
mixer.music.play()
35+
print(texts)
36+
37+
def listener(self):
38+
if self.mode == 'text':
39+
result = input()
40+
return result
41+
elif self.mode == 'voice1':
42+
result = None
43+
while(result == None):
44+
with Microphone() as source:
45+
# recognizer.adjust_for_ambient_noise(source)
46+
audio = self.recognizer.listen(source)
47+
try:
48+
result = self.recognizer.recognize_google(audio,language = 'zh-tw')
49+
except:
50+
continue
51+
print(result)
52+
return result
53+
elif self.mode == 'voice2':
54+
pass
55+
56+
def order_manage(self):
57+
data_dict = load_xlsx(file_name=menu_xlsx_path)
58+
menu_dict = process_data_to_menu(data_dict)
59+
self.line_speaker('您好,很高興為您服務,請問要做些甚麼?')
60+
while(1):
61+
order_line = self.listener()
62+
# 問好
63+
if '你好' in order_line:
64+
self.line_speaker('你好。')
65+
66+
# 有什麼吃的?
67+
elif '吃的' in order_line:
68+
eat_count = 0
69+
self.line_speaker('想吃飯還是麵?')
70+
while(eat_count<2):
71+
order_line = self.listener()
72+
if '飯' in order_line:
73+
self.line_speaker('我們沒有飯')
74+
eat_count+=1
75+
elif '麵' in order_line:
76+
self.line_speaker('我們沒有麵')
77+
eat_count+=1
78+
else:
79+
self.line_speaker('我們沒有這個')
80+
self.line_speaker('我們有水餃')
81+
continue
82+
83+
# 機率論
84+
elif '機率' in order_line:
85+
self.line_speaker('請描述你所要計算的機率問題。講完後請說我說完了')
86+
while(not '完' in order_line):
87+
order_line = self.listener()
88+
self.line_speaker('請問所求為會發生還是不會發生的機率?')
89+
order_line = self.listener()
90+
while(not '會' in order_line):
91+
order_line = self.listener()
92+
if '不會' in order_line:
93+
self.line_speaker('二分之一')
94+
else:
95+
self.line_speaker('二分之一')
96+
97+
# 點餐
98+
elif '餐' in order_line:
99+
total_order = ''
100+
self.line_speaker('請問要點些什麼呢?')
101+
while(1):
102+
order_menu_line = self.listener()
103+
if '和' in order_menu_line or '個' in order_menu_line:
104+
total_order+=order_menu_line+'和'
105+
elif '餐' in order_menu_line or '點完' in order_menu_line:
106+
# 點完餐
107+
break
108+
else:
109+
self.line_speaker('不好意思,請再說一次。')
110+
self.line_speaker(process_price_with_order(menu_dict, total_order))
111+
112+
# 問時間,幾點了
113+
elif ('時間' in order_line) or ('幾點' in order_line):
114+
now = datetime.now()
115+
res_text = '現在時間是 %d 點 %d 分 %d 秒' % (now.hour, now.minute, now.second)
116+
self.line_speaker(res_text)
117+
118+
# 離開
119+
elif '離開' in order_line or '結束' in order_line:
120+
self.line_speaker('很高興為您服務,很期待您下次光顧。')
121+
sleep(6)
122+
break
123+
124+
# not any option upper
125+
else:
126+
self.line_speaker('不好意思,請再說一次。')
127+
128+
def __call__(self):
129+
self.order_manage()
130+
131+
if __name__ == '__main__':
132+
order_bot = Order_Bot('text')
133+
order_bot.mode = 'voice1'
134+
order_bot()

script/order_bot/process_order.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import pandas as pd
2+
import re
3+
from setting import chinese_to_arabic
4+
chinese_char_dict = {
5+
'〇' : 0, '一' : 1, '二' : 2, '三' : 3, '四' : 4, '五' : 5, '六' : 6, '七' : 7, '八' : 8, '九' : 9, '零' : 0,
6+
'壹' : 1, '贰' : 2, '叁' : 3, '肆' : 4, '伍' : 5, '陆' : 6, '柒' : 7, '捌' : 8, '玖' : 9, '貮' : 2, '兩' : 2,
7+
}
8+
def load_xlsx(file_name = 'menu.xlsx'):
9+
xls = pd.ExcelFile(file_name)
10+
df = xls.parse(xls.sheet_names[0])
11+
df = df.T
12+
# print(df)
13+
# print(df.to_dict())
14+
return df.to_dict()
15+
16+
def write_xlsx(file_name = 'menu.xlsx'):
17+
menu = {
18+
"item":["滷肉飯","豆花", "燒肉", "雞腿"],
19+
"price":[1, 2, 3, 4],
20+
}
21+
df = pd.DataFrame(data=menu)
22+
# df = (df.T)
23+
# print (df)
24+
df.to_excel(file_name)
25+
26+
def process_data_to_menu(data_dict:dict):
27+
menu_dict = dict()
28+
for key in data_dict:
29+
menu_dict[data_dict[key]['item']]=data_dict[key]['price']
30+
# print(menu_dict)
31+
return menu_dict
32+
33+
def process_price_with_order(menu_dict, order):
34+
# format is 多少個什麼和多少個什麼
35+
order = re.split('和|個', order)
36+
37+
# using stack to process item and amount
38+
price_dict = dict()
39+
top = None
40+
for item in order:
41+
if item.isdigit():
42+
if top == None:
43+
top = item
44+
else:
45+
if item in chinese_char_dict:
46+
item = chinese_to_arabic(item)
47+
price_dict[top] = {'amount':item, 'price':None}
48+
top = None
49+
else:
50+
if top == None:
51+
top = item
52+
else:
53+
if top.isnumeric():
54+
top = chinese_to_arabic(top)
55+
top = int(top)
56+
price_dict[item] = {'amount':top, 'price':None}
57+
top = None
58+
59+
total = 0
60+
for item in price_dict:
61+
if item in menu_dict:
62+
price_dict[item]['price'] = price_dict[item]['amount'] * menu_dict[item]
63+
total += price_dict[item]['price']
64+
none_list = []
65+
for item in price_dict:
66+
if price_dict[item]['price']==None:
67+
none_list.append(item)
68+
69+
print(menu_dict)
70+
print(price_dict)
71+
# return total, none_list
72+
return sum_up_total_line(total, none_list)
73+
74+
def sum_up_total_line(total, none_list):
75+
total = format(total, ",")
76+
line = '總共是' + str(total) + '元。'
77+
if len(none_list)>0:
78+
line+='不過,我們沒有:'
79+
for item in none_list:
80+
line+=item + ', '
81+
return line
82+
83+
# write_xlsx()
84+
# data_dict = load_xlsx('script/menu.xlsx')
85+
# menu_dict = process_data_to_menu(data_dict)
86+
# print(process_price_with_order(menu_dict, '100個火腿和7000個蛋糕'))
87+
# print(process_price_with_order(menu_dict, '兩千萬個雞腿和兩個蛋糕'))

script/order_bot/setting.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
menu_xlsx_path = 'script/order_bot/menu.xlsx'
2+
def chinese_to_arabic(chinese_num):
3+
chinese_char_dict = {
4+
'〇' : 0, '一' : 1, '二' : 2, '三' : 3, '四' : 4, '五' : 5, '六' : 6, '七' : 7, '八' : 8, '九' : 9, '零' : 0,
5+
'壹' : 1, '贰' : 2, '叁' : 3, '肆' : 4, '伍' : 5, '陆' : 6, '柒' : 7, '捌' : 8, '玖' : 9, '貮' : 2, '兩' : 2,
6+
}
7+
chinese_char_unit = {
8+
'十' : 10,
9+
'拾' : 10,
10+
'百' : 100,
11+
'佰' : 100,
12+
'千' : 1000,
13+
'仟' : 1000,
14+
'万' : 10000,
15+
'萬' : 10000,
16+
'亿' : 100000000,
17+
'億' : 100000000,
18+
'兆' : 1000000000000,
19+
}
20+
unit = 0
21+
ldig = []
22+
# print(chinese_num)
23+
for char_digit in reversed(chinese_num):
24+
# print(char_digit)
25+
if chinese_char_unit.get(char_digit) != None:
26+
unit = chinese_char_unit.get(char_digit)
27+
# print("unit:"+str(unit))
28+
if unit == 10000 or unit == 100000000:
29+
ldig.append(unit)
30+
unit = 1
31+
else:
32+
dig = chinese_char_dict.get(char_digit)
33+
# print("num:"+str(dig))
34+
if unit:
35+
dig *= unit
36+
unit = 0
37+
ldig.append(dig)
38+
if unit == 10:
39+
ldig.append(10)
40+
val, tmp = 0, 0
41+
for x in reversed(ldig):
42+
if x == 10000 or x == 100000000:
43+
val += tmp * x
44+
tmp = 0
45+
else:
46+
tmp += x
47+
val += tmp
48+
return val
49+
50+
# print(chinese_to_arabic("九億七千八百萬八千八百八十八"))
51+
# print(chinese_to_arabic("一"))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from voice_detect import Voice_Detect_Helper
2+
3+
def using_audio_to_talk(file_name = 'test.wav'):
4+
from recording_voice import Recording_Helper
5+
recorder = Recording_Helper(file_name=file_name)
6+
voice_detecter = Voice_Detect_Helper(file_path=file_name)
7+
recorder.recording_voice()
8+
voice_detecter.detect_voice()
9+
# you can get result from voice_detecter.result
10+
11+
def using_detecter_to_talk(file_name = 'test.wav'):
12+
voice_detecter = Voice_Detect_Helper(file_path=file_name)
13+
voice_detecter.listener()
14+
15+
if __name__ == '__main__':
16+
# method 1 using pyaudio to record
17+
# using_audio_to_talk()
18+
19+
# method 2 using speech_recognition to record
20+
using_detecter_to_talk()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import pyaudio
2+
import wave
3+
4+
class Recording_Helper:
5+
def __init__(self, chunk = 1024, sample_format = pyaudio.paInt16, channels = 2, fs = 44100, seconds = 5, file_name = "test.wav"):
6+
# sample chunk size
7+
self.chunk = chunk
8+
# sample format: paFloat32, paInt32, paInt24, paInt16, paInt8, paUInt8, paCustomFormat
9+
self.sample_format = sample_format
10+
# sound channel
11+
self.channels = channels
12+
# sample frequency rate: 44100 ( CD ), 48000 ( DVD ), 22050, 24000, 12000 and 11025
13+
self.fs = fs
14+
# recording seconds
15+
self.seconds = seconds
16+
# recording file name
17+
self.file_name = file_name
18+
19+
self.p = pyaudio.PyAudio()
20+
# init pyaudio object
21+
22+
def recording_voice(self):
23+
print("starting recording...")
24+
25+
# active voice stream
26+
stream = self.p.open(format=self.sample_format, channels=self.channels, rate=self.fs, frames_per_buffer=self.chunk, input=True)
27+
28+
frames = []
29+
# voice list
30+
31+
for i in range(0, int(self.fs / self.chunk * self.seconds)):
32+
# record voice into list
33+
data = stream.read(self.chunk)
34+
frames.append(data)
35+
36+
# stop recording
37+
stream.stop_stream()
38+
# close stream
39+
stream.close()
40+
self.p.terminate()
41+
42+
print('stop recording...')
43+
44+
# open voice file
45+
wf = wave.open(self.file_name, 'wb')
46+
# set channel
47+
wf.setnchannels(self.channels)
48+
# set format
49+
wf.setsampwidth(self.p.get_sample_size(self.sample_format))
50+
# set sampling frequency rate
51+
wf.setframerate(self.fs)
52+
# save
53+
wf.writeframes(b''.join(frames))
54+
wf.close()
55+
56+
def __call__(self):
57+
self.recording_voice()

script/voice_detect/voice_detect.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import speech_recognition as sr
2+
class Voice_Detect_Helper:
3+
def __init__(self, language='zh-TW', file_path="test.wav"):
4+
self.language = language
5+
# default is english
6+
self.file_path = file_path
7+
self.r = sr.Recognizer()
8+
self.result = None
9+
def detect_voice(self):
10+
with sr.AudioFile(self.file_path) as source:
11+
# also you can use with sr.WavFile(self.file_path) as source:
12+
13+
# reduce ambient sound and noise
14+
# self.r.adjust_for_ambient_noise(source)
15+
16+
# load wav
17+
audio = self.r.record(source)
18+
19+
try:
20+
# using google service
21+
self.result = self.r.recognize_google(audio,language=self.language)
22+
print("Transcription: " + self.result)
23+
except:
24+
print("Could not understand audio")
25+
26+
def listener(self):
27+
with sr.Microphone() as source:
28+
audio = self.r.listen(source)
29+
try:
30+
# using google service
31+
self.result = self.r.recognize_google(audio,language=self.language)
32+
print("Transcription: " + self.result)
33+
return self.result
34+
except:
35+
print("Could not understand audio")
36+
37+
def __call__(self):
38+
self.listener()

0 commit comments

Comments
 (0)