3
\$\begingroup\$

My code:

import subprocess import os import platform class Speaker: """ Speaker class for differentiating different speech properties. """ def setVoice(self, voice): self.voice = voice def setWPM(self, wpm): self.wpm = wpm def setPitch(self, pitch): self.pitch = pitch def setProperties(self, voice="en", wpm=120, pitch=80): self.setVoice(voice) self.setWPM(wpm) self.setPitch(pitch) def __init__(self, voice="en", wpm=120, pitch=80): self.prevproc = None self.setProperties(voice, wpm, pitch) self.executable = os.path.dirname(os.path.abspath(__file__)) + "/espeak.exe" if platform.system() == 'Windows' else os.path.dirname(os.path.abspath(__file__)) + "/espeak" def generateCommand(self, phrase): cmd = [ self.executable, "--path=.", "-v", self.voice, "-p", self.pitch, "-s", self.wpm, phrase ] cmd = [str(x) for x in cmd] return cmd def say(self, phrase, wait4prev=False): cmd=self.generateCommand(phrase) if wait4prev: try: self.prevproc.wait() except AttributeError: pass else: try: self.prevproc.terminate() except AttributeError: pass self.prevproc = subprocess.Popen(cmd, executable=self.executable, cwd=os.path.dirname(os.path.abspath(__file__))) 

How can the above code be improved?

Find it on GitHub: https://github.com/sayak-brm/espeak4py

Usage:

import espeak4py import time print('Testing espeak4py\n') mySpeaker = espeak4py.Speaker() mySpeaker.say('Testing', wait4prev=True) print('Testing wait4prev') mySpeaker.say('Hello, World!') time.sleep(1) mySpeaker.say('Interrupted!') time.sleep(3) mySpeaker.say('Hello, World!') time.sleep(1) mySpeaker.say('Not Interrupted.', wait4prev=True) time.sleep(3) print('Testing pitch') myHighPitchedSpeaker = espeak4py.Speaker(pitch=120) myHighPitchedSpeaker.say('I am a demo of the say function') time.sleep(4) print('Testing wpm') myFastSpeaker = espeak4py.Speaker(wpm=140) myFastSpeaker.say('I am a demo of the say function') time.sleep(4) print('Testing voice') mySpanishSpeaker = espeak4py.Speaker(voice='es') mySpanishSpeaker.say('Hola. Como estas?') print('Testing Completed.') 
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

1.PEP8

Naming

In python functions/methods/variables are using underscore as a naming separator, but not a camelCase.

Quotes

You should pick one double or single quotes and use it everywhere that is a general rule, I prefer single ones so I've changed a code as I like, but you might want to use double, just follow one way to do that.

Please read code styling guide aka PEP8

2.Class definition

Methods order

I prefer to have __init__ and __new__ as first methods defined by class, this gives you better image on class and what it does and what it got. This is not a strong rule, but most of people and libraries are following it.

Properties definition

Most of the times you want to have all your properties defined in init, again that is not a strong rule, but in this particular case, I would define them inside __init__ instead of having a separate method to do that. If fact you I don't see much of use of your setProperties method, so I would just modify object attributes directly here if I would need it. Since there are no logics inside those methods except for changing an attribute to a value passed into it.

3.Improvements

I'm not a big fan of try:catch:pass statements you can avoid them with pre-conditions: so your say method can be modified like this:

def say(self, phrase, wait4prev=False): cmd = self.generate_command(phrase) if self.prevproc: if wait4prev: self.prevproc.wait() else: self.prevproc.terminate() self.prevproc = subprocess.Popen(cmd, cwd=os.path.dirname(os.path.abspath(__file__))) 

Note: you don't need to pass executable explicitly since it's already a part of your cmd param.

So in the end what we have is this:

import os import platform import subprocess class Speaker: """ Speaker class for differentiating different speech properties. """ def __init__(self, voice='en', wpm=120, pitch=80): self.prevproc = None self.voice = voice self.wpm = wpm self.pitch = pitch executable = 'espeak.exe' if platform.system() == 'Windows' else 'espeak' self.executable = os.path.join(os.path.dirname(os.path.abspath(__file__)), executable) def generate_command(self, phrase): cmd = [ self.executable, '--path=.', '-v', self.voice, '-p', self.pitch, '-s', self.wpm, phrase ] cmd = [str(x) for x in cmd] return cmd def say(self, phrase, wait4prev=False): cmd = self.generate_command(phrase) if self.prevproc: if wait4prev: self.prevproc.wait() else: self.prevproc.terminate() self.prevproc = subprocess.Popen(cmd, cwd=os.path.dirname(os.path.abspath(__file__))) 
\$\endgroup\$
1
  • \$\begingroup\$ I learnt a lot about Python today, thanks to you. I'll be sure to read up more about the PEP8 (I didn't know that something like that existed). \$\endgroup\$ Commented Jan 2, 2017 at 17:22

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.