2 de agosto de 2018

Repasando Python. Mi solución a "node disconnected users - SENDGRID"

def disconnected_users(net, users, source, crushes):
 
    suma=0 #total de mail-pigeons
    conectado={} #Diccionario de conectados o no...
 
    # print (net) 
    # 1/ marca la fuente como 1, el nodo roto como -1 y los demás como ceros.
    for i in users:
        conectado[i]=(i in source)-(i in crushes)
     
    # 2/ Busca en las listas si está al lado de uno conectado. Si lo está, le pone un uno.
    # hay una conexión a la fuente.
    for h in range(0,2): # dos pasadas al menos lo aseguran. Parecen estar las listas ordenadas, pero ¿y si no lo están?
        for j in net:
            for k in range(0,2): #límite superior 1
                # Si el otro es 1 y este es cero, lo cambia a uno. Si era 1 lo deja, y si era -1 tb lo deja.
                conectado[j[(k!=1)]]=(conectado[j[(k!=1)]]==1)-(conectado[j[(k!=1)]]==-1)+(conectado[j[k]]==1 and conectado[j[(k!=1)]]==0)
                # print(j,conectado[j[(k!=1)]],conectado) 
 
   # 3/ Sumo los valores de los que NO están en el diccionario
    for clave, valor in users.items():
        suma+=(conectado[clave]!=1)*valor
             
    # print("Suma: "+str(suma))
 
    return suma

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert disconnected_users([
        ['A', 'B'],
        ['B', 'C'],
        ['C', 'D']
    ], {
        'A': 10,
        'B': 20,
        'C': 30,
        'D': 40
    },
        'A', ['B']) == 90, "First"

    assert disconnected_users([
        ['A', 'B'],
        ['B', 'D'],
        ['A', 'C'],
        ['C', 'D']
    ], {
        'A': 10,
        'B': 0,
        'C': 0,
        'D': 40
    },
        'A', ['B']) == 0, "Second"

    assert disconnected_users([
        ['A', 'B'],
        ['A', 'C'],
        ['A', 'D'],
        ['A', 'E'],
        ['A', 'F']
    ], {
        'A': 10,
        'B': 10,
        'C': 10,
        'D': 10,
        'E': 10,
        'F': 10
    },
        'C', ['A']) == 50, "Third"

    print('Done. Try to check now. There are a lot of other tests')

Repasando python. Expresiones regulares. Resumen 2

https://docs.python.org/2/howto/regex.html
Generador de código: http://hilite.me/

Funciones a nivel de módulo - Module-Levels functions

No es necesario crear patrones. El módulo re también posee las funciones de alto nivel match(), search(), findall(), sub() y otras. Toman los mismos argumentos que los métodos de los patrones, con la expresión regular (RE) como primer argumento y la cadena a nalizar como segundo, devolviendo un objeto match o None.

>>> print re.match(r'From\s+', 'Fromage amk')
None
>>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')  
<_sre.SRE_Match object at 0x...>

= = = = = = = = =

Banderas - compilation flags.

Las banderas indican modificaciones de cómo vamos a trabajar con las expresiones regulares. Entre ellas tenemos:

DOTALL, S --> Coincide cualquier carácter, incluso caracteres de líneas nuevas.

I , IGNORECASE --> Representa la coincidencia tipo case-insensitive, es decir, dará coincidencia de letras independientemente si son o no mayúsculas o minúsculas.

L, LOCALE --> hace que \w, \W, \b, and \B dependan del modo local actual. "Locales" son una caracterśitica de la biblioteca de C que intenta ayudar a escribir programas que tienen  en cuenta las diferencias entre varias lenguas. Por ejemplo, \w representa la clase [A-Za-z] pero no tiene en cuenta la "Ñ" o la "ñ". Si el sistema está bien configurado, y el Locale en español está  seleccionado, al activar la bandera LOCALE, el sistema considerará que la Ñ entra dentro de la clase [A-Z]. Activar esta bandera ralentiza algo el programa. 

M, MULTILINE --> ^ produce una coincidencia al principio de la cadena y $ al final de la misma e 

inmediatamente antes de una nueva línea (si existe)al final de la cadena. Cuando esta bandera está 

activa, ^ coincide al principio de la cadena y al principio de cada línea dentro de la cadena. De forma

idéntica, $ coincide al final de la cadena y al final de cada línea (inmediatamente antes del carácter línea nueva).

U,UNICODE --> Hacen a las clases \w, \W, \b, \B, \d, \D, \s y \S depender de la base de datos UNICODE.

X, VERBOSE --> Te permite escribir RE más fáciles de leer. Si lo activo, se ignoran los espacios en 

blanco, excepto cuando forman parte de la misma clase o están antecedidos por \. También permite  escribir comentarios con #

charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

charref = re.compile("&#(0[0-7]+"
                     "|[0-9]+"
                     "|x[0-9a-fA-F]+);")

Con y sin la bandera re.VERBOSE

= = = = = = = = = 

Más metacaracteres

| --> Operador OR.
^ --> Al principio. A menos que la bandera MULTILINE esté activa, se aplica al principio de la cadena.
Por ejemplo, buscar la palabra From al principio de la cadena:

>>> print re.search('^From', 'From Here to Eternity')
<_sre.SRE_Match object at 0x...>
>>> print re.search('^From', 'Reciting From Memory')
None

$ --> Al final. O justo antes de un carácter de nueva línea.

>>> print re.search('}$', '{block}')
<_sre.SRE_Match object at 0x...>
>>> print re.search('}$', '{block} ')
None
>>> print re.search('}$', '{block}\n')
<_sre.SRE_Match object at 0x...>

\A --> al principio de la cadena como ^ , pero si estoy en el modo multilínea, \A sólo lo hará al principio de la cadena y no al principio de cada línea.
\Z --> Sólo al final de la cadena.
\b --> "Contorno de palabra" Sólo se aplica al final o al principio de una palabra, si está está entre espacios en blanco o signos de puntuación.

Ejemplo:


>>> p = re.compile(r'\bclass\b')
>>> print p.search('no class at all')
<_sre.SRE_Match object at 0x...>
>>> print p.search('the declassified algorithm')
None
>>> print p.search('one subclass is')
None

\b hay que usarlo como literal. Si no puede haber confusión con el carácter BACKSPACE.

\B--> Opuesto a \b

= = = = = = = = = = = 

Agrupando - Grouping

A veces necesitamos más información que sólo si una expresión regular coincide o no. A veces necesitamos que una expresión regular detecte si hay varios grupos de caracteres en una cadena que cumplan determinadas condiciones. Por ejemplo, en la cabecera de un mensaje con el estándar RFC-822, debemos determinar si existen varios grupos separados con nombre:valor.

From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
MIME-Version: 1.0
To: editor@example.com

Construimos grupos con los metacaracteres ( y ) , los paréntesis. Y a estos grupos se les puede aplicar los metacaracteres *, + , ? y {m,n}

Por ejemplo, coincidencia del grupo ab repetido...

>>> p = re.compile('(ab)*')
>>> print p.match('ababababab').span()
(0, 10)

Los grupos están indexados. El índice se puede pasar como argumento a group(), start(), end(), and span() y el índice cero, siempre que se cree un grupo, siempre existe. Por lo tanto, el grupo 0 siempre existe y coincide con el resultado de la expresión regular RE. Los métodos de los objetos match siempre tienen cero por índice por defecto.


>>> p = re.compile('(a)b')
>>> m = p.match('ab')
>>> m.group()
'ab'
>>> m.group(0)
'ab'

Los subgrupos se numeran de izquierda a derecha, desde el uno hacia arriba. Para saber el múmero de un subgrupo simplemente cuenta el número de paréntesis de apertura de izquierda a derecha:


>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'

Para que devuelva una lista con todos los grupos: m.groups()
Para que devuelva una lista con grupos específicos: m.group(2,1,3)



Detectar palabras repetidas



>>> p = re.compile(r'\b(\w+)\s+\1\b')
>>> p.search('Paris in the the spring').group()
'the the'

Usamos texto raw para escribir solamente un \ .  La expresión significa:

  • (\w+) grupo de más de 1 carácter alfanumérico. Es el grupo 1
  • \s+ ...seguido de 1 o más espacios en blanco
  • \1 ...seguido del grupo número 1 (las llaman referencias traseras o backreferences)
  • Entre \b y \b, o sea, palabra completa

= = = = = = = = =

Grupos con nombre y no capturados - Non-capturing and Named Groups 

Construir expresiones regulares puede consistir en crear muchos grupos. Bien para destacar subcadenas, o bien para estructurar la expresión regular. A veces es difícil seguir la numeración de los subgrupos. Hay dos características que nos ayudan en este seguimiento; ambas usan una sintaxis común para la extensión de expresiones regulares.

Si en la sintaxis uso (?...) , ? no tiene nada que repetir. Se aprovecha esta circunstancia para indicar (en Perl o Python) que si tenemos (?=foo) 

Si quiero un grupo no-capturado, uso la sintaxis ?: como en el ejemplo...


>>> m = re.match("([abc])+", "abc")
>>> m.groups()
('c',)
>>> m = re.match("(?:[abc])+", "abc")
>>> m.groups()
()

Si quiero un grupo con nombre, necesito la sintaxis (?P<name>...). Por ejemplo:


>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'
>>> m.group(1)
'Lots'

He creado el grupo llamado "palabra", "word".

Y las referencias anteriores que se hacían con números \1  ahora se pueden referenciar con la sintaxis (?P=name)


La expresión regular para encontrar palabras dobles, \b(\w+)\s+\1\b se puede escribir como \b(?P<word>\w+)\s+(?P=word)\b:



>>> p = re.compile(r'\b(?P<word>\w+)\s+(?P=word)\b')
>>> p.search('Paris in the the spring').group()
'the the'

= = = = = = = = = 

Aseveraciones hacia adelante - lookahead assertions

Forma positiva (?=...) y forma negativa (?!...). Tiene éxito si la expresión regular que contiene coincide (positiva) ( o no coincide - negativa) en la posición actual, y falla en caso contrario. 

Por ejemplo, la expresión .*[.].*$ coincidirá con cualquier nombre de fichero punto extensión. "Punto" representa cualquier carácter que se repetirá 0 o más veces más un punto (clase punto [.]) más, visto desde el final de la expresión, repetirá 0 o más veces un carácter .*

Intentemos ahora varios intentos de encontrar ficheros con extensión que no sea bat. Por ejemplo:

.*[.][^b].*$  intento para que el primer carácter no sea "b". Pero claro, también excluye otros ficheros, como prueba.bar.

.*[.]([^b]..|.[^a].|..[^t])$ en esta expresión se intenta que no acepte una extensión cuyo primer carácter es b, cuyo segundo es a y cuyo tercero es t. De acuerdo, no aceptará un fichero bat. Pero tampoco uno del tipo prueba.cf con tan sólo dos caracteres. No sirve.

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$ Este patrón incluyendo ? toma los segundos caracteres y tercero como opcionales. Vale, lo consigue. Pero es poco legible. Y lo que es peor, si quiero excluir los ficheros con extensión bat y exe, se complicaría aún más.

Pero usando una aseveración negativa: .*[.](?!bat$)[^.]*$  que significa: si no coincide el patrón bat, sigue evaluando. Y llegará a que desde el final encontrará cualesquiera caracteres que no sean puntos.

Si coincide el patrón bat, da una coincidencia negativa y falla. y ahora para incluir la extensión exe ya es fácil: .*[.](?!bat$|exe$)[^.]*$

= = = = = =

Cortando cadenas

.split(string[, maxsplit=0]) --> corta por las coincidencias del patrón. Si maxsplit no es cero, corta las veces que explicita. 


>>> p = re.compile(r'\W+')
>>> p.split('This is a test, short and sweet, of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test, short and sweet, of split().', 3)
['This', 'is', 'a', 'test, short and sweet, of split().']

Si quiero además que aparezca el delimitador, pongo el patrón entre paréntesis.


>>> p = re.compile(r'\W+')
>>> p2 = re.compile(r'(\W+)') ### Delimitador entre paréntesis.
>>> p.split('This... is a test.')
['This', 'is', 'a', 'test', '']
>>> p2.split('This... is a test.')
['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']

Y como función a nivel de módulo:


>>> re.split('[\W]+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('([\W]+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('[\W]+', 'Words, words, words.', 1)
['Words', 'words, words.']

= = = = = = = = =

Búsqueda y reemplazo

.sub(reemplazo, cadena[, cuenta=0]) --> retorna una cadena que se obtiene sustituyendo el reemplazo en la cadena, según coincida o no con el patrón. Lo hace las veces que se especifique en "cuenta".

>>> p = re.compile('(blue|white|red)')
>>> p.sub('colour', 'blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub('colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'

.subn hace lo mismo, pero retorna una tupla con la cadena nueva y las veces que ha realizado el reemplazo.

>>> p = re.compile('(blue|white|red)')
>>> p.subn('colour', 'blue socks and red shoes')
('colour socks and colour shoes', 2)
>>> p.subn('colour', 'no colours at all')
('no colours at all', 0)

Si el reemplazo es una cadena, cualquier carácter \ en ella se procesa. \n se convierte en una nueva línea, \r en retorno de carro y así sucesivamente. Las referencias traseras, como \1, se reemplazan con la correspondiente subcadena correspondiente al grupo de la expresión regular.

En este ejemplo se hace coincidir la palabra section por una cadena cerrada entre llaves y cambiamos section a subsection.


>>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First} section{second}')
'subsection{First} subsection{second}'

También hay una sintaxis para referirse a un grupo con nombre en los reemplazos. Todas son equivalentes. Cuidado con la sintaxis \g<1>0 porque puede interpretarse como la '10'


>>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
>>> p.sub(r'subsection{\1}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<1>}','section{First}')
'subsection{First}'
>>> p.sub(r'subsection{\g<name>}','section{First}')
'subsection{First}'

El reemplazo también puede ser una función, el resultado de ella. Se le pasa a la función el objeto match correspondiente. El siguiente ejemplo encuentra números decimales y los sustituye por hexadecimales:


>>> def hexrepl(match):
...     "Return the hex string for a decimal number"
...     value = int(match.group())
...     return hex(value)
...
>>> p = re.compile(r'\d+')
>>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
'Call 0xffd2 for printing, 0xc000 for user code.'

Si utilizamos funciones a nivel de módulo re.sub() , el primer parámetro es el patrón.

= = = = = = = = = = =

Algunos problemas

  • Algunas veces el empleo del módulo re está desaconsejado porque es más lento que métodos de cadenas ad hoc. Por ejemplo, si simplemente quiero sustituir una palabra por otra mejor usar el método replace(). O translate() para borrar un carácter o modificarlo por otro.
  • Recordar que match() dará las coincidencias si empieza desde cero, si no hay que usar search().
  • Greedy or not greedy (ávaro o no ávaro): el uso del carácter * es avaricioso. De tal forma que encuentra hasta la última instancia del mismo. Esto a veces da resultados no deseados. Para evitarlo, se usa caracteres no avariciosos como ?
  • # AVARICIOSO
    >>> s = '<html><head><title>Title</title>'
    >>> len(s)
    32
    >>> print re.match('<.*>', s).span()
    (0, 32)
    >>> print re.match('<.*>', s).group()
    <html><head><title>Title</title>
    
    # NO AVARICIOSO
    >>> print re.match('<.*?>', s).group()
    <html>
    
  • Es mejor usar , por mor de la claridad, la bandera re.VERBOSE


29 de julio de 2018

Repasando python. Expresiones regulares. Resumen 1


Usando el módulo re (patrones-patterns estilo Perl). Módulo regex para estilo Emacs

Las expresiones regulares son un tipo especial de programación dentro de Python, cuyo objetivo es trabajar con cadenas de caracteres, para buscar coincidencias y así saber si las cadenas que tenemos, por ejemplo, son direcciones, emails, código de algún lenguaje, o multitud de otras aplicaciones. 

Patrones simples - Simple Patterns

Coincidencia de caracteres - matching characters

Por ejemplo, la cadena hola y la cadena hola coinciden exactamente. Si tenemos activado un modo de case-insensitive además coincidirán las cadenas Hola y HoLa exactamente.

En expresiones regulares usamos también caracteres especiales o metacaracteres. Estos metacaracteres representan no un carácter, sino un conjunto de ellos, o una repetición, etc. por lo que no coinciden en principio. Los metacaracteres son:

. ^ $ * + ? { } [ ] \ | ( )

[ ] - Brackets o corchetes.

Indican una clase de caracteres, bien uno a uno, o bien entre un rango (separados por un guión). Por ejemplo, para indicar las letras a, b y c, podemos escribir [abc] o [a-c]. Todas las letras minúsculas pueden ser [a-z].

Si escribo [abc$] aunque $ sea un metacaracter, dentro de una clase, se refiere al caracter $.

Clase complementaria. Uso el metacaracter ^. Por ejemplo, la clase de todos los caracteres excepto el 5 sería [^5].

\ - Backslash o barra diagonal invertida

Este metacaracter es muy importante. Indica que lo que le sigue es una clase especial. Por ejemplo:
  • \d --> Coincide cualquier dígito. Equivale a la clase [0-9].
  • \D --> Coincide cualquier carácter que no sea un dígito. Equivale a [^0-9].
  • \s --> Coincide cualquier carácter "espacio en blanco". Equivale a [ \t\n\r\f\v].
  • \S --> Coincide cualquier carácter que no sea "espacio en blanco". Equivale [^ \t\n\r\f\v].
  • \w --> Coincide cualquier carácter alfanumérico. Equivale a [a-zA-Z0-9_].
  • \W --> Coincide cualquier carácter no alfanumérico. Equivale a [^a-zA-Z0-9_].
También indica que si le sigue un metacaracter estamos analizando ese carácter. Por ejemplo , la referencia a \$ indica el carácter $.

Estas clases pueden formar, a su vez, otras clases. Por ejemplo, [\s,.] indica la clase de los caracteres espacios en blanco más el punto más la coma.

. Punto

El metacaracter punto '.' coincide con cualquier cosa excepto un carácter de nueva línea. El modo alternativo es re.DOTALL (incluso coincidiendo con una nueva línea). A menudo el punto se usa para indicar "cualquier carácter".

= = = = = = = =

Repitiendo cosas - repeating things

No sólo utilizamos las expresiones regulares para las coincidencias, sino para repetir cosas. Por ejemplo, la expresión ca*t (usando el metacaracter asterisco) coincidirá con ct (0 a carácter), cat (1 a), caaat (3 a caracteres). Se lee "a" cualquier número de veces...

Otro carácter de repetición es + (más). Funciona igual que * pero diferencia que no acepta 0 repeticiones del asterisco. Por eso ca+t no tiene coincidencia con ct. Se lee "a" por lo menos una vez...

El carácter ? indica la aparición una 0 cero veces. Por ejemplo home-?brew muestra coincidencia con homebrew y home-brew.


Y la última forma es {a,b}, repeticiones desde a veces hasta b veces. Por ejemplo a\{1,3}b indicará coincidencia con a\b , a\\b y a\\\b. 

* se puede expresar como {0,} , + como {1,} y ? como {0,1}, pero no se suele hacer.



= = = = = = = =

Usando expresiones regulares - Using Regular Expressions


Compilando expresiones regulares
Usamos el módulo re para compilar una expresión regular. 

>>> import re
>>> p = re.compile('ab*')
>>> p  
<_sre.SRE_Pattern object at 0x...>

También acepta banderas como

>>> p = re.compile('ab*', re.IGNORECASE)

Python trata las expresiones regulares como cadenas, y las pasa al módulo programado en C re.


The Backslash Plague - La plaga de la barra diagonal
Ya sabemos que se usa la barra invertida para denotar caracteres especiales o clases. Imaginemos que queremos compilar los caracteres \seccionEn este caso, tenemos que indicar el carácter literal de barra invertida con otra barra antecediéndola \\seccion al introducirlo en re.compile() . Pero si queremos expresarlo como una cadena lietral de Python, necesitamos "\\\\seccion"

Por eso a veces usamos en Python la notación raw: r"ab" (antecediendo con r).

Regular StringRaw string
"ab*"r"ab*"
"\\\\section"r"\\section"
"\\w+\\s+\\1"r"\w+\s+\1"

Representando coincidencias - Performing Matches
Tenemos los siguientes métodos o atributos, entre otros:


Method/AttributePropósito
match()Determina si la expresión regular coincide al principio de la cadena.
search()Busca por toda la cadena, buscando la localización donde coincida
findall()Encuentra todas las subcadenas que coincidan con la expresión y las devuelve en forma de lista.
finditer()
Encuentra todas las subcadenas que coincidan con la expresión y las devuelve en forma de iterador (iterator).

El resultado de un programa con match es o bien None (sin coincidencias) o un objeto tipo match con información sobre la misma.


import re
p = re.compile('[a-z]+')
m = p.match("tiempo")
print m

En este caso el resultado es <_sre.SRE_Match object at 0x7f2749ff3648>

Para extraer información de este objeto, necesitamos varios métodos o atributos. Entre los más importantes tenemos:

Métodos / atributosPropósito
group()Devuelve la cadena que coincide con la expresión regular.
start()Devuelve la posición inicial de la coincidencia.
end()Devuelve la posición final de la coincidencia.
span()Devuelve una tupla con la posición inicial y final.


import re
p = re.compile('[a-z]+')
m = p.match("tiempo")
print m.group()
print m.start(),m.end()
print m.span()

Dando como resultado

tiempo
0 6
(0, 6)

Otro ejemplo


# *-* coding: utf-8 *-*

import re
p = re.compile('[a-z]+')
# en este caso, dará None, ya que busca DESDE el principio de la cadena.
print p.match(":::message")
# En este caso, mostrará el objeto match, y se puede obtener información su aparición.
m=p.search(":::message")
print m
print m.group()
print m.span()

Dando como resultado

None
<_sre.SRE_Match object at 0x7fa9a11f3648>
message
(3, 10)


findall() devuelve una lista de cadenas coincidentes


>>> p = re.compile('\d+')

>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords fQa-leaping')

['12', '11', '10']

findall() tiene que crear la lista completa antes de devolverla como el resultado. El método finditer() devuelve objetos tipo match que pueden ser iterados.


>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator 
<callable-iterator object at 0x...>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)


28 de julio de 2018

Repasando python. Solución a "Stressful subject - SENDGRID"

def is_stressful(subj):
    """
        recoognise stressful subject       
    """
    stwords=["help","asap","urgent"]
    condition = False
    if subj==subj.upper(): condition = True
    if subj[-3:]=="!!!": condition = True
    # filtrando caracteres y quedándose con letras
    newSubj1=[]
    for a in subj.upper():
        if a.isalpha():
            newSubj1.append(a)
    # Quitando caracteres repetidos
    newSubj2=[]
    for indice, a in enumerate(newSubj1):
        if not (indice>1 and a==newSubj1[indice-1]):
            newSubj2.append(a)
    newSubj2Str="".join(newSubj2)
    print(newSubj2Str)
    # Reconociendo palabras de stwords
    for a in stwords:
        if newSubj2Str.find(a.upper())>=0:
            condition = True
    return condition

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert is_stressful("Aquí hay una HHHELLLLPPPP!!!")==True,"Mine"
    assert is_stressful("Hi") == False, "First"
    assert is_stressful("I neeed HELP") == True, "Second"
    print('Done! Go Check it!')

6 de febrero de 2018

Parámetros de seguridad global ADOBE FLASH PLAYER y problema de shockwave player

Parámetros seguridad global adobe flash player

Acceder a esa página web. Si sale algo como que Adobe flash no está permitido con la ventanita que se ve en negro con un icono de error, pulsar sobre esa ventanita,  y “permitir” y, si deja, “permitir y recordar”.






Escoger la opción PERMITIR SIEMPRE.

Ahora, pulsar en EDITAR y escoger AGREGAR.

BUSCAR CARPETAS

Seleccionar la carpeta /home/usuario

Al final debe quedar así.



El problema de no ejecutarse cierto contenido en las pizarras digitales de la Junta de Andalucía puede resolverse en parte con la configuración del plugin de Shockwave Flash en Mozilla-Firefox.

Acceder en el Mozilla-Firefox a Herramientas>>Complementos y acceder al Plugin de Shockwave Flash (preferencias). Desmarcar "Bloquear contenido Flash peligroso e intrusivo" y ACTIVAR SIEMPRE.