forked from souljourner/Watson_Hackathon_SF_Interviewer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterviewer.py
158 lines (138 loc) · 6.74 KB
/
interviewer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from watson_developer_cloud import TextToSpeechV1, SpeechToTextV1, NaturalLanguageUnderstandingV1 as NLU
import watson_developer_cloud.natural_language_understanding.features.v1 as features
from recorder import Recorder
import pyaudio
import wave
import os
import json
import numpy as np
import pandas as pd
from streamcharts import StreamCharts
import datetime
import time
import webbrowser
class Interviewer(object):
def __init__(self, ):
self.MIN_ANSWER_LEN = 5
self.MIN_CONFIDENCE = 0.60
self.SMALL_TALK = ['I see.', 'Got it.', 'Ok', 'Interesting']
self.POSITIVE_REMARK = ["Good.", "Excellent!", "Sounds great!", "That's awesome!", "Wonderful!"]
self.NEGATIVE_REMARK = ["I'm sad to hear that.", "That doesn't sound very good.", "I'm sad to hear that.", "ah", "Someone forgot to have their coffee today"]
self.questions = ['Tell me about yourself',
'Tell me about a recent project that you worked on',
'What are your greatest weaknesses?',
'What did you dislike the most about your last job?',
'If you were an animal, which one would you want to be?',
'What are your hobbies?',
'What is your greatest professional achievement?',
'Why do you want to work here?',
'What are your strengths?',
'Where do you see yourself in five years?',
'What type of work environment do you prefer?',
"What's a time you disagreed with a decision that was made at work?",
'Why was there a gap in your employment?',
'Can you explain why you changed career paths?',
'How do you deal with pressure or stressful situations?',
'What would your first 30, 60, or 90 days look like in this role?',
'What are your salary requirements?',
'How many tennis balls can you fit into a limousine?',
'Are you planning on having children?',
'How many ping pong balls fit on a 737?',
'Describe a difficult work situation / project and how you overcame it',
'How are you different from the competition?',
'Do you take work home with you?',
'How do you view yourself? Whom do you compare yourself to?',
'What motivates you',
'What did you like most about your last job?',
'What did you dislike most about your last job?',
'Why should I take a risk on you?']
self.text_to_speech = TextToSpeechV1(
x_watson_learning_opt_out=True) # Optional flag
self.speech_to_text = SpeechToTextV1(
x_watson_learning_opt_out=False)
self.nlu = NLU(
version='2017-02-27')
self.TEMPFILE = './temp/output.wav'
self.answers, self.sentiments = [], []
def transcribe_audio(self, stt, path_to_audio_file):
with open(self.TEMPFILE, 'rb') as audio_file:
return stt.recognize(audio_file,content_type='audio/wav')
def say(self, text, output_filename='./temp/output.wav'):
if os.path.isfile(output_filename):
os.remove(output_filename)
with open(output_filename,'wb') as audio_file:
audio_file.write(self.text_to_speech.synthesize(text, accept='audio/wav',
voice="en-US_AllisonVoice"))
chunk = 1024
f = wave.open(output_filename,"rb")
p = pyaudio.PyAudio()
stream = p.open(format = p.get_format_from_width(f.getsampwidth()),
channels = f.getnchannels(),
rate = f.getframerate(),
output = True)
data = f.readframes(chunk)
while data:
stream.write(data)
data = f.readframes(chunk)
stream.stop_stream()
stream.close()
p.terminate()
def listen(self):
if os.path.isfile(self.TEMPFILE):
os.remove(self.TEMPFILE)
recorder = Recorder(self.TEMPFILE)
print('Recording')
recorder.record_to_file()
print('Stopped')
confidence, transcript = 0, ''
result = self.transcribe_audio(self.speech_to_text, self.TEMPFILE)
if len(result['results']) > 0:
confidence = result['results'][0]['alternatives'][0]['confidence']
transcript = result['results'][0]['alternatives'][0]['transcript'].strip()
return transcript, confidence
def analyze_sentiment(self, answer):
result = self.nlu.analyze(text=answer,features=[features.Keywords(),features.Sentiment()])
if result['keywords']:
keywords = result['keywords'][0]
keyword = keywords['text']
else:
keyword = None
sentiment = result['sentiment']['document']['score']
return sentiment, keyword
def discuss_sentiment(self, sentiment, keyword):
if sentiment < -0.45:
self.say(self.NEGATIVE_REMARK[np.random.choice(range(len(self.NEGATIVE_REMARK)))])
elif sentiment > 0.25:
self.say(self.POSITIVE_REMARK[np.random.choice(range(len(self.POSITIVE_REMARK)))])
if np.random.rand() > 0.25 and keyword:
self.say("I'd like to hear more about " + keyword + " next time")
else:
self.say(self.SMALL_TALK[np.random.choice(range(len(self.SMALL_TALK)))])
def run_interview(self):
self.answers, self.sentiments = [], []
chart = StreamCharts(window_size=20)
webbrowser.open(chart.chart_url, new=2)
time.sleep(10)
i = 0
self.say('Let us begin the interview.')
while i < len(self.questions):
self.say(self.questions[i])
answer, confidence = self.listen()
if (len(answer) >= self.MIN_ANSWER_LEN) and (confidence >= self.MIN_CONFIDENCE):
sentiment, keyword = self.analyze_sentiment(answer)
self.answers.append(answer)
self.sentiments.append(sentiment)
i += 1
self.discuss_sentiment(sentiment, keyword)
if not keyword:
keyword = ""
x_label = keyword #" ".join(answer.split()[:5])
y_value = sentiment
chart.update(x_label=x_label, y_value=y_value)
elif confidence < self.MIN_CONFIDENCE:
self.say("Let's try that again, I couldn't understand you.")
elif len(answer) < self.MIN_ANSWER_LEN:
self.say("Let's try that again, please provide a longer answer.")
self.say("Thank you for your time. We will get back to you shortly about our decision. Thank you, and thank you Galvanize and IBM Cognitive Builder Faire.")
# Close the stream when done plotting
chart.close()