#!/usr/bin/env python # -*- coding: iso-8859-15 -*- # /usr/local/bin/scatolo.py # ######################################################################## # File : scatolo.py # Project : scatolo talking Machine # Version : 1.0.0 # Author : giodim & Unit team # Comment : # 06.07.2017 - Version 1.0.0 developement ######################################################################## # Copyright 2015 GioDim # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. ######################################################################## ######################################################################## # Import ######################################################################## import os import time import subprocess import random from string import ascii_letters from random import choice ######################################################################## # Constants ######################################################################## DADA_FILE = "scatolo_v0.1_iotunoi.pb" MARKOV_FILE = "macao.txt" EDITED_FILE = "humor.txt" DADA_CMD = "dada" GEN_CMD = "/usr/local/bin/pico.sh" PLAY_CMD = ["aplay", "tmp.wav"] MAX_RND = 100 DADA_WEIGHT = 30 MARKOV_WEIGHT = 90 MARKOV_MAX_WORD = 20 ######################################################################## # Global Variables ######################################################################## Debug = True Word_List = [] Associations = [] Humor_Text = [] ######################################################################## # Class : _Getch # Comment : ######################################################################## class _Getch: """Gets a single character from standard input. Does not echo to the screen.""" def __init__(self): try: self.impl = _GetchWindows() except ImportError: self.impl = _GetchUnix() def __call__(self): return self.impl() ######################################################################## # Class : _GetchUnix # Comment : ######################################################################## class _GetchUnix: def __init__(self): import tty, sys def __call__(self): import sys, tty, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch ######################################################################## # Class : _GetchWindows # Comment : ######################################################################## class _GetchWindows: def __init__(self): import msvcrt def __call__(self): import msvcrt return msvcrt.getch() ######################################################################## # Function : Markov_Get_Word_List # Input : # Output : # Comment : ######################################################################## def Markov_Get_Word_List (text) : # Define a set of allowed letters allowed_letters = ascii_letters + "áàéèíìóòúù" + "ÁÀÉÈÍÌÓÒÚÙ" + "'." # Keep only the allowed replacing the others with a space text = "".join (c.lower () if c in allowed_letters else " " for c in text) # Split by words, using space as separator return text.split () ######################################################################## # Function : Markov_Get_Associations # Input : # Output : # Comment : ######################################################################## def Markov_Get_Associations (word_list): # Build a dictionary where each word is a key, and the values are the list # of the words that follow the key one # ['a', 'b', 'a', 'c'] became {'a': ['b', 'c'], 'b': ['a']} associations = {} for i, word in enumerate(word_list[:-1]): if word not in associations: associations[word] = [] associations[word].append(word_list[i+1]) return associations ######################################################################## # Function : Markov_Build_Chains # Input : # Output : # Comment : ######################################################################## def Markov_Build_Chains (text) : global Word_List global Associations Word_List = Markov_Get_Word_List (text) Associations = Markov_Get_Associations (Word_List) ######################################################################## # Function : Markov_Generator # Input : # Output : # Comment : ######################################################################## def Markov_Generator (max_words=MARKOV_MAX_WORD): out_list = [] current_word = choice (Word_List) for i in range (max_words): out_list.append(current_word) choice_list = Associations.get (current_word, Word_List) if current_word.endswith ("."): break current_word = choice (choice_list) out_string = " ".join (out_list) out_string = out_string.replace (" .", ".") out_string = out_string [0].upper () + out_string [1:] return out_string ######################################################################## # Function : Dada_Generator # Input : # Output : # Comment : ######################################################################## def Dada_Generator (nomef) : if (not os.path.exists (nomef)) : return " " testo_dada = subprocess.check_output ([DADA_CMD, nomef]) testo_dada.replace ('\n', '').replace ('\r', '') return testo_dada ######################################################################## # Function : File_Load # Input : # Output : # Comment : ######################################################################## def File_Load (nomef) : global Humor_Text if (not os.path.exists (nomef)) : return for buf in open (nomef) : Humor_Text.append (buf.rstrip ('\n')) ######################################################################## # Function : File_Rand_Generator # Input : # Output : # Comment : ######################################################################## def File_Rand_Generator () : return choice (Humor_Text) ######################################################################## # Function : Play # Input : # Output : # Comment : ######################################################################## def Play (text_to_play) : if (text_to_play == "") or (text_to_play == " ") : return if (Debug == True) : print (text_to_play) subprocess.call ([GEN_CMD, text_to_play]) subprocess.check_output (PLAY_CMD) ######################################################################## # Function : # Input : # Output : # Comment : ######################################################################## random.seed () mygetch = _Getch() with open (MARKOV_FILE) as f: Markov_Build_Chains (f.read()) File_Load (EDITED_FILE) while (True) : print "prompt ", ch = mygetch () if (ch != " ") : time.sleep (1) continue idx = int (random.random () * MAX_RND) if (Debug == True) : print ("Idx=", idx) if (idx < DADA_WEIGHT) : if (Debug == True) : print ("DADA ") testo = Dada_Generator (DADA_FILE) elif (idx >= DADA_WEIGHT) and (idx < MARKOV_WEIGHT) : if (Debug == True) : print ("MARKOV ") testo = Markov_Generator () else : if (Debug == True) : print ("FILE ") testo = File_Rand_Generator () Play (testo)