Versione attualmente installata del sw Scatolo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

300 lines
8.1KB

  1. #!/usr/bin/env python
  2. # -*- coding: iso-8859-15 -*-
  3. # /usr/local/bin/scatolo.py
  4. #
  5. ########################################################################
  6. # File : scatolo.py
  7. # Project : scatolo talking Machine
  8. # Version : 1.0.0
  9. # Author : giodim & Unit team
  10. # Comment :
  11. # 06.07.2017 - Version 1.0.0 developement
  12. ########################################################################
  13. # Copyright 2015 GioDim <giodim1317@gmail.com>
  14. #
  15. # This program is free software; you can redistribute it and/or modify
  16. # it under the terms of the GNU General Public License as published by
  17. # the Free Software Foundation; either version 2 of the License, or
  18. # (at your option) any later version.
  19. #
  20. # This program is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. # GNU General Public License for more details.
  24. #
  25. # You should have received a copy of the GNU General Public License
  26. # along with this program; if not, write to the Free Software
  27. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  28. # MA 02110-1301, USA.
  29. ########################################################################
  30. ########################################################################
  31. # Import
  32. ########################################################################
  33. import os
  34. import time
  35. import subprocess
  36. import random
  37. from string import ascii_letters
  38. from random import choice
  39. ########################################################################
  40. # Constants
  41. ########################################################################
  42. DADA_FILE = "scatolo_v0.1_iotunoi.pb"
  43. MARKOV_FILE = "macao.txt"
  44. EDITED_FILE = "humor.txt"
  45. DADA_CMD = "dada"
  46. GEN_CMD = "/usr/local/bin/pico.sh"
  47. PLAY_CMD = ["aplay", "tmp.wav"]
  48. MAX_RND = 100
  49. DADA_WEIGHT = 30
  50. MARKOV_WEIGHT = 90
  51. MARKOV_MAX_WORD = 20
  52. ########################################################################
  53. # Global Variables
  54. ########################################################################
  55. Debug = True
  56. Word_List = []
  57. Associations = []
  58. Humor_Text = []
  59. ########################################################################
  60. # Class : _Getch
  61. # Comment :
  62. ########################################################################
  63. class _Getch:
  64. """Gets a single character from standard input. Does not echo to the screen."""
  65. def __init__(self):
  66. try:
  67. self.impl = _GetchWindows()
  68. except ImportError:
  69. self.impl = _GetchUnix()
  70. def __call__(self): return self.impl()
  71. ########################################################################
  72. # Class : _GetchUnix
  73. # Comment :
  74. ########################################################################
  75. class _GetchUnix:
  76. def __init__(self):
  77. import tty, sys
  78. def __call__(self):
  79. import sys, tty, termios
  80. fd = sys.stdin.fileno()
  81. old_settings = termios.tcgetattr(fd)
  82. try:
  83. tty.setraw(sys.stdin.fileno())
  84. ch = sys.stdin.read(1)
  85. finally:
  86. termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
  87. return ch
  88. ########################################################################
  89. # Class : _GetchWindows
  90. # Comment :
  91. ########################################################################
  92. class _GetchWindows:
  93. def __init__(self):
  94. import msvcrt
  95. def __call__(self):
  96. import msvcrt
  97. return msvcrt.getch()
  98. ########################################################################
  99. # Function : Markov_Get_Word_List
  100. # Input :
  101. # Output :
  102. # Comment :
  103. ########################################################################
  104. def Markov_Get_Word_List (text) :
  105. # Define a set of allowed letters
  106. allowed_letters = ascii_letters + "áàéèíìóòúù" + "ÁÀÉÈÍÌÓÒÚÙ" + "'."
  107. # Keep only the allowed replacing the others with a space
  108. text = "".join (c.lower ()
  109. if c in allowed_letters else " "
  110. for c in text)
  111. # Split by words, using space as separator
  112. return text.split ()
  113. ########################################################################
  114. # Function : Markov_Get_Associations
  115. # Input :
  116. # Output :
  117. # Comment :
  118. ########################################################################
  119. def Markov_Get_Associations (word_list):
  120. # Build a dictionary where each word is a key, and the values are the list
  121. # of the words that follow the key one
  122. # ['a', 'b', 'a', 'c'] became {'a': ['b', 'c'], 'b': ['a']}
  123. associations = {}
  124. for i, word in enumerate(word_list[:-1]):
  125. if word not in associations:
  126. associations[word] = []
  127. associations[word].append(word_list[i+1])
  128. return associations
  129. ########################################################################
  130. # Function : Markov_Build_Chains
  131. # Input :
  132. # Output :
  133. # Comment :
  134. ########################################################################
  135. def Markov_Build_Chains (text) :
  136. global Word_List
  137. global Associations
  138. Word_List = Markov_Get_Word_List (text)
  139. Associations = Markov_Get_Associations (Word_List)
  140. ########################################################################
  141. # Function : Markov_Generator
  142. # Input :
  143. # Output :
  144. # Comment :
  145. ########################################################################
  146. def Markov_Generator (max_words=MARKOV_MAX_WORD):
  147. out_list = []
  148. current_word = choice (Word_List)
  149. for i in range (max_words):
  150. out_list.append(current_word)
  151. choice_list = Associations.get (current_word, Word_List)
  152. if current_word.endswith ("."):
  153. break
  154. current_word = choice (choice_list)
  155. out_string = " ".join (out_list)
  156. out_string = out_string.replace (" .", ".")
  157. out_string = out_string [0].upper () + out_string [1:]
  158. return out_string
  159. ########################################################################
  160. # Function : Dada_Generator
  161. # Input :
  162. # Output :
  163. # Comment :
  164. ########################################################################
  165. def Dada_Generator (nomef) :
  166. if (not os.path.exists (nomef)) :
  167. return " "
  168. testo_dada = subprocess.check_output ([DADA_CMD, nomef])
  169. testo_dada.replace ('\n', '').replace ('\r', '')
  170. return testo_dada
  171. ########################################################################
  172. # Function : File_Load
  173. # Input :
  174. # Output :
  175. # Comment :
  176. ########################################################################
  177. def File_Load (nomef) :
  178. global Humor_Text
  179. if (not os.path.exists (nomef)) :
  180. return
  181. for buf in open (nomef) :
  182. Humor_Text.append (buf.rstrip ('\n'))
  183. ########################################################################
  184. # Function : File_Rand_Generator
  185. # Input :
  186. # Output :
  187. # Comment :
  188. ########################################################################
  189. def File_Rand_Generator () :
  190. return choice (Humor_Text)
  191. ########################################################################
  192. # Function : Play
  193. # Input :
  194. # Output :
  195. # Comment :
  196. ########################################################################
  197. def Play (text_to_play) :
  198. if (text_to_play == "") or (text_to_play == " ") :
  199. return
  200. if (Debug == True) :
  201. print (text_to_play)
  202. subprocess.call ([GEN_CMD, text_to_play])
  203. subprocess.check_output (PLAY_CMD)
  204. ########################################################################
  205. # Function :
  206. # Input :
  207. # Output :
  208. # Comment :
  209. ########################################################################
  210. random.seed ()
  211. mygetch = _Getch()
  212. with open (MARKOV_FILE) as f:
  213. Markov_Build_Chains (f.read())
  214. File_Load (EDITED_FILE)
  215. while (True) :
  216. print "prompt ",
  217. ch = mygetch ()
  218. if (ch != " ") :
  219. time.sleep (1)
  220. continue
  221. idx = int (random.random () * MAX_RND)
  222. if (Debug == True) :
  223. print ("Idx=", idx)
  224. if (idx < DADA_WEIGHT) :
  225. if (Debug == True) :
  226. print ("DADA ")
  227. testo = Dada_Generator (DADA_FILE)
  228. elif (idx >= DADA_WEIGHT) and (idx < MARKOV_WEIGHT) :
  229. if (Debug == True) :
  230. print ("MARKOV ")
  231. testo = Markov_Generator ()
  232. else :
  233. if (Debug == True) :
  234. print ("FILE ")
  235. testo = File_Rand_Generator ()
  236. Play (testo)