#! /usr/bin/env python
# coding: latin-1

import sys
import re
import random
from PyQt4 import QtCore, QtGui
from math import *

# Clase grafica
class PolinomiosQt(QtGui.QWidget):
  # Constructor
  def __init__(self):
    super(PolinomiosQt, self).__init__()
    #
    gArriba = QtGui.QGridLayout()
    bChk = QtGui.QPushButton("Comprobar")
    bChk.clicked.connect( self.comprobar )
    bVerSolu = QtGui.QPushButton("Corregir")
    bVerSolu.clicked.connect( self.corregir )
    bGenPdf = QtGui.QPushButton("Generar PDFs")
    bGenPdf.clicked.connect( self.generarPdfs )
    bSig = QtGui.QPushButton("Siguiente")
    bSig.clicked.connect( self.siguiente )
    gArriba.addWidget(bChk, 0, 0)
    gArriba.addWidget(bVerSolu, 0, 1)
    gArriba.addWidget(bGenPdf, 0, 2)
    gArriba.addWidget(bSig, 0, 3)
    #
    gProblema = QtGui.QFormLayout()
    self.lPoli1 = QtGui.QLabel("p1(x) = ")
    self.lPoli2 = QtGui.QLabel("p2(x) = ")
    self.lOper = QtGui.QLabel("p1(x) ? p2(x) = ")
    self.iSolu = QtGui.QLineEdit()
    self.iSolu.editingFinished.connect( self.comprobar )
    gProblema.addRow(self.lPoli1)
    gProblema.addRow(self.lPoli2)
    gProblema.addRow(self.lOper, self.iSolu)
    #
    self.libreta = QtGui.QPlainTextEdit()
    #
    gCalcu = QtGui.QHBoxLayout()
    lCalcu = QtGui.QLabel("CALCULADORA: ")
    self.calcu = QtGui.QLineEdit()
    self.calcu.editingFinished.connect( self.calcular )
    lIgual = QtGui.QLabel(" = ")
    self.resulCalcu = QtGui.QLabel("")
    gCalcu.addWidget(lCalcu)
    gCalcu.addWidget(self.calcu)
    gCalcu.addWidget(lIgual)
    gCalcu.addWidget(self.resulCalcu)
    #
    grid = QtGui.QVBoxLayout()
    grid.setSpacing(10)
    grid.addItem(gArriba)
    grid.addItem(gProblema)
    grid.addWidget(self.libreta)
    grid.addItem(gCalcu)
    #
    self.setLayout(grid)
    #
    self.setWindowTitle("Ejercicios de polinomios")
    self.setFixedSize(900, 700)
    self.show()
    self.siguiente()
  #
  def corregir(self):
    self.comprobar(verSolu=True)
  #
  def comprobar(self, verSolu=False):
    mSuSolu = {}
    suSolu = str( self.iSolu.text() )
    signo = "+"
    num = None
    for bloque in re.split("([-+])", suSolu):
      if re.search("([-+])", bloque):
        signo = bloque
      else:
        ###print("bloque=[%s]" % bloque)
        m = re.search("\s*(?P<num>\d*)\s*(?P<x>[x]?)\^?(?P<expo>[2-9]?)\s*", bloque)
        if m:
          num = int(signo + m.group('num')) if m.group('num') else 1
          if m.group('x'):
            expo = int( m.group(3) ) if m.group('expo') else 1
          else:
            expo = 0
          mSuSolu[expo] = num
          ###print("expo = %d -> num = %d" % (expo, num))
        else:
          print("ERROR con bloque=[%s]" % bloque)
    suTam = (max(mSuSolu.keys()) + 1) if mSuSolu.keys() else 0
    vSuSolu = [ 0 ] * suTam
    for expo in mSuSolu:
      vSuSolu[expo] = mSuSolu[expo]
    ###print("vSuSolu = %s" % vSuSolu)
    cadInfo = self.vectorToCadPoli(vSuSolu, "Alumno: ") + "\n"
    #
    vMiSolu = []
    if self.operacion == '+':
      tam = max(len(self.vPoli1), len(self.vPoli2))
      vMiSolu = [ 0 ] * tam
      for expo in xrange(tam):
        num1 = 0 if expo >= len(self.vPoli1) else self.vPoli1[expo]
        num2 = 0 if expo >= len(self.vPoli2) else self.vPoli2[expo]
        vMiSolu[expo] = num1 + num2
    elif self.operacion == '-':
      tam = max(len(self.vPoli1), len(self.vPoli2))
      vMiSolu = [ 0 ] * tam
      for expo in xrange(tam):
        num1 = 0 if expo >= len(self.vPoli1) else self.vPoli1[expo]
        num2 = 0 if expo >= len(self.vPoli2) else self.vPoli2[expo]
        vMiSolu[expo] = num1 - num2
    elif self.operacion == '*':
      tam = len(self.vPoli1) + len(self.vPoli2)
      vMiSolu = [ 0 ] * tam
      for expo1 in xrange( len(self.vPoli1) ):
        num1 = 0 if expo >= len(self.vPoli1) else self.vPoli1[expo]
        for expo2 in xrange( len(self.vPoli1) ):
          num2 = 0 if expo >= len(self.vPoli2) else self.vPoli2[expo]
          vMiSolu[expo1+expo2] = vMiSolu[expo1+expo2] + num1 * num2
    #
    if verSolu:
      cadInfo = cadInfo + self.vectorToCadPoli(vMiSolu, "Profesor: ") + "\n"
    #
    ###print("vMiSolu = %s" % vMiSolu)
    if vSuSolu == vMiSolu:
      cadInfo = cadInfo + "==> CORRECTO\n"
    else:
      cadInfo = cadInfo + "==> ERROR\n"
    #
    self.libreta.setPlainText(cadInfo)
  #
  def generarPdfs(self):
    pass
  #
  def siguiente(self):
    # Inventa operacion y polinomios
    self.operacion = random.sample(['+', '-', '*'], 1)[0]
    maxGrado = 5
    if self.operacion == '*':
      maxGrado = 3
    grado1 = random.randint(2, maxGrado)
    self.vPoli1 = []
    while sum(self.vPoli1) == 0:
      self.vPoli1 = random.sample(range(-9, 10), grado1)
    while self.vPoli1[-1] == 0:
      self.vPoli1 = self.vPoli1[:-1]
    grado2 = random.randint(2, maxGrado)
    self.vPoli2 = []
    while sum(self.vPoli2) == 0:
      self.vPoli2 = random.sample(range(-9, 10), grado2)
    while self.vPoli2[-1] == 0:
      self.vPoli2 = self.vPoli2[:-1]
    # Escribe el enunciado
    self.lPoli1.setText( self.vectorToCadPoli(self.vPoli1, "p1(x) = ") )
    self.lPoli2.setText( self.vectorToCadPoli(self.vPoli2, "p2(x) = ") )
    self.lOper.setText("p1(x) %s p2(x) = " % self.operacion)
    self.libreta.setPlainText("%s\n%s\n" % (self.lPoli1.text(), self.lPoli2.text()))
    self.iSolu.setText("")
  #
  def vectorToCadPoli(self, v, cadPre):
    cad = cadPre
    ###print v
    for expo in xrange(len(v)-1, -1, -1):
      if v[expo] == 0:
        continue
      monomio = ""
      if v[expo] < 0:
        monomio = "- "
      elif v[expo] > 0:
        monomio = "+ "
      if (expo == 0) or (v[expo] != 1):
        monomio = monomio + "%d" % abs(v[expo])
      if expo == 1:
        monomio = monomio + " x "
      elif expo > 1:
        monomio = monomio + " x^%d " % expo
      ###print("monomio = %s" % monomio)
      cad = cad + monomio
    ###print cad
    return(cad)
  #
  def calcular(self):
    try:
      calculo = str( self.calcu.text() )
      self.resulCalcu.setText( str(eval(calculo)) )
    except:
      self.resulCalcu.setText("ERROR")
#
# Programa principal
#
apli = QtGui.QApplication(sys.argv)
ventana = PolinomiosQt()
sys.exit( apli.exec_() )
