Advertisement
Sax

PyZap v4

Sax
May 9th, 2013
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.62 KB | None | 0 0
  1. #PyZap v4
  2. # -*- coding: utf-8 -*-
  3.  
  4. #TODO
  5.  
  6. #MAJOR --> Agregar distintos diccionarios
  7.  
  8. #minor -> untogglear botones con clear
  9. #minor -> agregar un nuevo shortcut en letras repetidas
  10. #minor -> de-focusear botones después de oprimidos
  11. #minor -> selector grafico de specs iniciales (dificultad, diccionario)
  12.  
  13. import random
  14. import csv
  15. import sys
  16. import unittest as u
  17. from PySide import QtGui, QtCore
  18.  
  19. class MainWindow(QtGui.QMainWindow):
  20.  
  21.     def __init__(self, parent=None):
  22.         super(MainWindow, self).__init__(parent)
  23.  
  24.         self.initUI()
  25.  
  26.    
  27.     def closeEvent(self, event):
  28.         reply = QtGui.QMessageBox.question(self, "Aviso",
  29.                 "Seguro que quieres salir?",
  30.                 QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
  31.                 QtGui.QMessageBox.No)
  32.  
  33.         if reply == QtGui.QMessageBox.Yes:
  34.             masusadas.seek(2)
  35.             masusadas.writelines(most_used)
  36.         else:
  37.             event.ignore()
  38.  
  39.     def initUI(self):
  40.         """Inicia la Ventana del juego."""
  41.  
  42.         self.statusBar().showMessage('Listo.')
  43.  
  44.         self.widget = MainWidget()
  45.         self.setCentralWidget(self.widget)
  46.  
  47.         self.setGeometry(300, 300, 300, 300)
  48.         self.setWindowTitle('PyZap')
  49.         self.setWindowIcon(QtGui.QIcon('icon.png'))
  50.         self.show()
  51.  
  52. class MainWidget(QtGui.QWidget):
  53.    
  54.         def __init__(self, parent=None):
  55.             super(MainWidget, self).__init__(parent)
  56.             self.init_ui()
  57.  
  58.         def init_ui(self):
  59.             #Aqui van las weas graficas
  60.  
  61.             self.grid= QtGui.QGridLayout()
  62.             self.grid.setSpacing(10)
  63.  
  64.             self.letter_grid = QtGui.QGridLayout()
  65.             self.letter_grid.setSpacing(10)
  66.  
  67.             pos = [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1),
  68.                    (2,2), (3,0), (3,1), (3,2), (4,0), (4,1), (4,2), (5,0),
  69.                    (5,1), (5,2)]
  70.             j = 0
  71.  
  72.             for i in pyzap.letras_escogidas:
  73.                 button = QtGui.QPushButton(i)
  74.                 button.setShortcut(str(i))
  75.                 button.setCheckable(True)
  76.                 button.clicked[bool].connect(self.typea)
  77.                 self.letter_grid.addWidget(button, pos[j][0], pos[j][1])
  78.                 j = j + 1
  79.  
  80.             self.line_edit = QtGui.QTextEdit()
  81.             self.line_edit.setReadOnly(True)
  82.             self.line_edit.setMaximumHeight(25)
  83.  
  84.             self.grid.addLayout(self.letter_grid, 0, 0)
  85.  
  86.             self.clear_button = QtGui.QPushButton('Clear')
  87.             self.clear_button.clicked.connect(self.line_edit.clear)
  88.  
  89.             self.ok_button = QtGui.QPushButton("OK")
  90.             self.ok_button.setShortcut("Enter")
  91.             self.ok_button.clicked.connect(self.send)
  92.            
  93.             self.grid.addWidget(self.clear_button, 0, 1)
  94.             self.grid.addWidget(self.line_edit, 1, 0, 1, 1)
  95.             self.grid.addWidget(self.ok_button, 2, 1)
  96.            
  97.             self.grid.addWidget(QtGui.QLabel("Tus Palabras"), 2,0)
  98.  
  99.             self.reset_button = QtGui.QPushButton('Reset')
  100.             self.reset_button.setShortcut("F2")
  101.             self.reset_button.clicked.connect(self.reset)
  102.  
  103.             self.grid.addWidget(self.reset_button, 3, 1)
  104.  
  105.             self.tus_palabras = QtGui.QTextEdit()
  106.             self.tus_palabras.setReadOnly(True)
  107.  
  108.             self.grid.addWidget(self.tus_palabras, 3, 0, 1, 1)
  109.  
  110.             self.setLayout(self.grid)
  111.             self.show()
  112.                    
  113.                                                
  114.  
  115.  
  116.         def typea(self, pressed):
  117.             """Escribe el texto del boton."""
  118.  
  119.             source = self.sender()
  120.  
  121.             if pressed:
  122.                  self.line_edit.insertPlainText(source.text())
  123.             else:
  124.                 self.line_edit.clear()
  125.                
  126.  
  127.         def send(self):
  128.             """Envia word para ser validada. Regresa texto si succedea."""
  129.  
  130.             word = self.line_edit.toPlainText()
  131.             print "La palabra enviada fue " + str(word) #debug
  132.            
  133.             self.line_edit.clear()
  134.  
  135.             valid = self.validate_word(word)
  136.  
  137.             if valid:
  138.                 repeated = self.check_repeated(word)
  139.                 if not repeated:
  140.                     pyzap.your_words.append(word)
  141.                     self.tus_palabras.append(word)
  142.                     total_used.append(word)
  143.                     self.mark_as_most_used(word)
  144.                     window.statusBar().showMessage("Correcto!")
  145.                 else:
  146.                     self.line_edit.insertPlainText(
  147.                     "Ya usaste esa palabra!")
  148.                     window.statusBar().showMessage(
  149.                     "Ya usaste esa palabra!")
  150.             else:
  151.                 self.line_edit.insertPlainText(
  152.                     "Esa palabra no se puede formar o no existe")
  153.                 window.statusBar().showMessage(
  154.                     "Esa palabra no se puede formar o no existe!")
  155.  
  156.             if len(pyzap.your_words) == 10:
  157.                 #ShowDialogBox diciendo que ganaste
  158.                 msg = QtGui.QMessageBox.information(self, "Felicidades!",
  159.                                                     "Has logrado formar 10 palabras!")
  160.  
  161.         def reset(self):
  162.             """Reinicia la corrida del programa."""
  163.             global pyzap, window
  164.  
  165.             window.statusBar().showMessage("Reiniciando. Por favor espere...")
  166.             pyzap = PyZap()
  167.             window = MainWindow()
  168.            
  169.  
  170.         def validate_word(self, word):
  171.             """Valida que la palabra este presente en el diccionario."""
  172.             return word in pyzap.palabras2
  173.  
  174.         def check_repeated(self, word):
  175.             """Valida que la palabra no haya sido usada antes."""
  176.             return word in pyzap.your_words
  177.  
  178.         def mark_as_most_used(self, word):
  179.             """Registra una palabra comunmente usada."""
  180.             if word in total_used:
  181.                 if total_used.count(word) > diff:
  182.                     most_used.append("\n" + word)
  183.  
  184.         def check_common(self, word):
  185.             """Revisa que la palabra no sea comunmente usada."""
  186.             if word in most_used:
  187.                 window.statusBar().showMessage("Usas esta palabra con frecuencia. Piensa en otra!")
  188.  
  189.            
  190.  
  191. class PyZap(object):
  192.    
  193.     def __init__(self, parent=None):
  194.  
  195.         self.init_mind()
  196.  
  197.     def init_mind(self):
  198.         """Inicia procesos de la aplicacion."""
  199.  
  200.         print "--------------------------------------------" #Debug
  201.         print "Iniciando..." #Debug
  202.  
  203.         self.alpha = self.create_alpha()
  204.         print "Alfabeto creado correctamente" #Debug
  205.         print "--------------------------------------------" #Debug
  206.        
  207.         self.letras_escogidas = self.get_sample()
  208.         print "Letras de la corrida: " + str(self.letras_escogidas)
  209.         print "--------------------------------------------" #Debug
  210.  
  211.         print "Comenzando busqueda lv1 en diccionario seleccionado..." #debug
  212.         self.palabras1 = self.first_search(
  213.             self.letras_escogidas)
  214.  
  215.         print "Busqueda lv1 concluida.\nComenzando busqueda lv2..." #debug
  216.         self.palabras2 = self.second_search(
  217.             self.palabras1, self.letras_escogidas)
  218.         print "Hecho." #Debug
  219.         print "--------------------------------------------" #Debug
  220.  
  221.         print "Coincidencias:"
  222.         print self.palabras2
  223.  
  224.         self.your_words = []
  225.  
  226.     def create_alpha(self):
  227.         """Regresa el alfabeto a utilizar en el PyZap."""
  228.         zipo= []
  229.         letters = list("abcdefghijklmnopqrstuvwxyz")
  230.         archivo.seek(0)
  231.  
  232.         for row in reader:
  233.             zipo.append(tuple(row))
  234.  
  235.         for (char,proba) in zipo:
  236.             for i in range(int(proba)):
  237.                 letters.append(char)
  238.  
  239.         return letters
  240.  
  241.     def get_sample(self):
  242.         """Regresa una muestra de LETRAS letras entre el alfabeto disponible.
  243.        LETRAS es una constante definida en el main().
  244.  
  245.        """
  246.  
  247.         chosen = random.sample(self.alpha,LETRAS)
  248.  
  249.         for el in chosen:
  250.             if el is "a" or el is "e"or el is "i" or el is "o" or el is "u":
  251.                 check = True
  252.                 break
  253.             else:
  254.                 check = False
  255.  
  256.         if check is False:
  257.             self.get_sample()
  258.         else:
  259.             return chosen
  260.  
  261.     def first_search(self, search_terms):
  262.         """Realiza la primera busqueda de palabras dentro de 'diccionario' que
  263.        contengan cualquier elemento de search_terms.
  264.  
  265.        Los search_terms son una sola lista de caracteres. Cada elemento de la
  266.        lista es una letra.
  267.  
  268.        Tras haber encontrado las palabras, las copia a un diccionario a RAM
  269.        en el siguiente formato:
  270.  
  271.        'palabra' : num_de_coincidencias, num_de_caracteres
  272.  
  273.        Regresa el diccionario antes mencionado.
  274.  
  275.        """
  276.        
  277.         results = []
  278.  
  279.         for word in ram:
  280.             for term in search_terms:
  281.                 if word.find(term) != -1:
  282.                     results.append(word)
  283.  
  284.         first_search_words = {}
  285.  
  286.         for word in results:
  287.             if word not in first_search_words:
  288.                 first_search_words[word] = [results.count(word), len(word)]
  289.  
  290.         return first_search_words
  291.  
  292.     def second_search(self, first_search_words, search_terms):
  293.         """Recibe el diccionario en ram con las first_search_words para refinar
  294.        la busqueda.
  295.  
  296.        Primero se eliminan los resultados que tengan menos coincidencias que
  297.        numero de caracteres. Posteriormente, cada palabra es separada en
  298.        caracteres, y se comparan uno a uno con las letras escogidas en el run.
  299.  
  300.        Regresa una lista de palabras.
  301.  
  302.        """
  303.  
  304.         flagged_for_deletion = []
  305.  
  306.         for word in first_search_words:
  307.             if first_search_words.get(word)[0] < first_search_words.get(word)[1]:
  308.                 flagged_for_deletion.append(word)
  309.  
  310.         for word in flagged_for_deletion:
  311.             del first_search_words[word]
  312.  
  313.         used_chars = []
  314.         final_words = []
  315.         keys = first_search_words.keys()
  316.  
  317.         for word in keys:
  318.  
  319.             available = list(search_terms)
  320.             used_chars[:] = []
  321.             actual_word = list(word)
  322.  
  323.             for current_char in actual_word:
  324.                 if current_char in available:
  325.                     used_chars.append(current_char)
  326.                     available.remove(current_char)
  327.  
  328.             actual_word.sort()
  329.             used_chars.sort()
  330.             available[:] = []
  331.  
  332.             if actual_word == used_chars:
  333.                 final_words.append(word)
  334.  
  335.         return final_words
  336.    
  337.  
  338. #----------- PRUEBAS UNITARIAS  -----------#
  339.  
  340. class TestMainWidget(u.TestCase):
  341.    
  342.     def test_validate_word(self):
  343.         """Revisa que el return type de validate_word sea un booleano."""
  344.         self.assertEqual(type(window.widget.validate_word("prueba")), bool,
  345.                          "No es booleano!")
  346.  
  347.     def test_check_repeated(self):
  348.         """Revisa que el return type de check_repeated sea un booleano."""
  349.         self.assertEqual(type(window.widget.check_repeated("prueba")), bool,
  350.                          "No es booleano!")
  351.  
  352.  
  353. class TestPyZap(u.TestCase):
  354.  
  355.     def test_create_alpha(self):
  356.         """Revisa haya al menos una vez cada letra en el alfabeto."""
  357.         archivo.seek(0)
  358.  
  359.         alpha = pyzap.create_alpha()
  360.         self.assertIn("a", alpha)
  361.         self.assertIn("b", alpha)
  362.         self.assertIn("c", alpha)
  363.         self.assertIn("d", alpha)
  364.         self.assertIn("e", alpha)
  365.         self.assertIn("f", alpha)
  366.         self.assertIn("g", alpha)
  367.         self.assertIn("h", alpha)
  368.         self.assertIn("i", alpha)
  369.         self.assertIn("j", alpha)
  370.         self.assertIn("k", alpha)
  371.         self.assertIn("l", alpha)
  372.         self.assertIn("m", alpha)
  373.         self.assertIn("n", alpha)
  374.         self.assertIn("o", alpha)
  375.         self.assertIn("p", alpha)
  376.         self.assertIn("q", alpha)
  377.         self.assertIn("r", alpha)
  378.         self.assertIn("s", alpha)
  379.         self.assertIn("t", alpha)
  380.         self.assertIn("u", alpha)
  381.         self.assertIn("v", alpha)
  382.         self.assertIn("w", alpha)
  383.         self.assertIn("x", alpha)
  384.         self.assertIn("y", alpha)
  385.         self.assertIn("z", alpha)
  386.  
  387.     def test_get_sample(self):
  388.         """Revisa que la muestra sea de el numero de letras especificado y
  389.        tenga al menos una vocal.
  390.  
  391.        """
  392.         sam = pyzap.get_sample()
  393.        
  394.         self.assertEqual(len(sam), LETRAS,
  395.                          "El numero de letras escogidas no coincide!")
  396.  
  397.         self.assertTrue(
  398.             "a" in sam or "e" in sam or "i" in sam or "o" in sam or "u" in sam,
  399.             "No hay vocales en las letras escogidas!")
  400.  
  401.     def test_first_search(self):
  402.         """Revisa que la first search regrese al menos una palabra."""
  403.  
  404.         words = pyzap.palabras1
  405.         self.assertGreater(len(words), 0, "No lanzo resultados!")
  406.  
  407.     def test_second_search(self):
  408.         """Revisa que la second search regrese al menos una palabra."""
  409.  
  410.         words = pyzap.palabras2
  411.         self.assertGreater(len(words), 0, "No lanzo resultados!")
  412.  
  413. def main():
  414.  
  415.     app = QtGui.QApplication(sys.argv)
  416.     global reader, diccionario, archivo, pyzap, window, LETRAS, ram
  417.     global most_used, total_used, masusadas, diff
  418.  
  419.     diff = 1
  420.  
  421.     if diff == 2: #Easy
  422.         LETRAS = 18
  423.     elif diff == 1: #Normal
  424.         LETRAS = 9
  425.     else: #Hard
  426.         LETRAS = 6
  427.        
  428.     FILE = "diccionario"
  429.  
  430.     archivo = open('probas.csv', 'r+')
  431.     diccionario = open(FILE, 'r+')
  432.     masusadas = open('mostusedwords', 'a+')
  433.     reader = csv.reader(archivo, delimiter=',')
  434.  
  435.     ram = []
  436.     most_used = []
  437.     total_used = []
  438.  
  439.     for word in diccionario:
  440.         word = word.rstrip()
  441.         ram.append(word)
  442.  
  443.     for word in masusadas:
  444.         word = word.rstrip()
  445.         most_used.append(word)
  446.  
  447.     pyzap = PyZap()
  448.     window = MainWindow()
  449.  
  450.     sys.exit(app.exec_())
  451.    
  452. if __name__ == '__main__':
  453.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement