How to validate if a value is a tuple having a string and an integer? [closed]

0

I want to write a function that takes an argument (any type) and returns true if the argument is a tuple (double, double elements of 2), where 1 is a name ( str ) and 2 is an age (% with%). Otherwise it returns int .

My first draft:

def verifica(tuplo):

    tuplo = ( (joao,39), (paulo,15), (andre,14), (simao,21) )    

resultado = isinstance(tuplo[0],str)

return (isinstance(tuplo[0],str)    
return (isinstance(tuplo[1],int)   

I know I should have a False cycle. When invoking the function, would not it be supposed to have 2 fields? Something like name and age?

Ex: IF - if the combo is in tuple, it returns a verifica(joao,39) ?

    
asked by anonymous 05.11.2018 / 11:32

3 answers

3

I will start from the premise that you forgot to put quotation marks around your strings. So the correct tuple would be:

(('joao', 39), ('paulo', 15), ('andre', 14), ('simao', 21))

From this you need to know how to test the type of a variable correctly. You can use the type() method and compare directly to the type you want, such as by example:

if type(variavel) == tuple:
    print('É uma tupla')

But it is worth remembering that in this way there is no subclass checking, ie in the example above, if variavel was of a subclass of tuple the print would not run because there is no subclass check.

To perform this check, simply use the isinstance() method, which checks if the variable is of the requested type or if it is of some subclass of the type asked. Example:

if isinstance(variavel, tuple):
    print('É um tupla ou subclasse de tupla')

The use of one or the other will depend on the requirements of your software, but as a general rule I use isinstance() because it is very likely that the subclass behaves like the parent class.

That said, all you would need to do is test the 4 requirements you want, which are:

  • Variable is tuple
  • This tuple has only two elements
  • First element of tuple is str
  • Second element of tuple is int
  • You would have something like:

    def verifica(variavel):
        return isinstance(variavel, tuple) \
            and len(variavel) == 2 \
            and isinstance(variavel[0], str) \
            and isinstance(variavel[1], int)
    

    For the sake of curiosity, instead of using and you can use the method all() that returns True only if all received parameters are also True . The complete example would look like this:

    def verifica(variavel):
        return all((
            isinstance(variavel, tuple),
            len(variavel) == 2,
            isinstance(variavel[0], str),
            isinstance(variavel[1], int)
        ))
    
    dados = (
        ('joao', 39),     # True
        (b'andre', 14),   # False pois 1º elemento não é str
        ('paulo', 15.3),  # False pois 2º elemento não é int
        ('simao', 21, 0)  # False pois não contém exatamente 2 elementos
    )
    
    for d in dados:
        print(verifica(d))
    

    Repl.it with the working code

    Edit : added the tuple size check (Suggestion: @ anderson-carlos-woss).

    Edit 2

    As there still seem to be doubts about how to apply the verifica() function to all elements of a sequence, not just an element, I'll elaborate.

    The function verifica() receives a tuple and checks if the tuple pattern is correct:

    tupla_valida = ('Tupla válida', 0)
    verifica(tupla_valida)  # True
    

    If you want to check all tuples in a sequence, you can go through this sequence using a for loop and test one by one. If some of them are False there you choose what your program should do about it.

    Example, check if the sequence contains only valid tuples:

    tuplas = (('joao', 39), ('paulo', 15), ('andre', 14), (0, 'Inválida'))
    
    todas_validas = True  # Valor inicial
    
    for tupla in tuplas:
        if not verifica(tupla):
            # se alguma tupla for inválida atribui False e sai do loop
            todas_validas = False
            break
    
    if todas_validas:
        print("Todas as tuplas são válidas")
    else:
        print("A sequência contém alguma tupla inválida")
    

    Repl.it with the code working

    If you have any questions about the above code, study a little about for and break .

    I'll leave as an example to study, an alternative to the previous code that uses the method all() mentioned above and list comprehensions to arrive at the same result.

    tuplas = (('joao', 39), ('paulo', 15), ('andre', 14), (0, 'Inválida'))
    
    # aplica a função 'verifica' em todos os elementos da tupla e passa
    # a lista resultante para o método 'all'
    # nesse caso o método 'all' recebe: (True, True, True, False)
    todas_validas = all([verifica(tupla) for tupla in tuplas])
    
    if todas_validas:
        print("Todas as tuplas são válidas")
    else:
        print("A sequência contém alguma tupla inválida")
    

    Repl.it with the working code

        
    05.11.2018 / 12:08
    0

    If I understand correctly, you want a function that takes the code and see if it is of type tuple, if it is, get position 0 and see if it is string and position 1 and see if it is int ... Here is the code:

    def verifica(variavel):
        #If para saber se é uma tupla
        if type(variavel) is tuple:
            #Caso seja tupla, vamos verificar se o primeiro elemento é str e o segundo int
            if (type(variavel[0]) is str) and (type(variavel[1]) is int):
                return True
            else:
                return False
        return False
    
    verifica(('matheus',1))
    

    PS: I used python 2.7

        
    05.11.2018 / 11:44
    0

    Use the isinstance function by passing each element and type. Here is a function that generalizes this idea:

    def verificar_tipos(tupla, tipos):
        return all(isinstance(elemento, tipo) for elemento, tipo in zip(tupla, tipos))
    

    You use it this way:

    verificar_tipos(('joao', 23), (str, int)) # retorna True
    verificar_tipos(('joao', 23), (str, str)) # retorna False
    

    If you have a list of tuples, just make one by calling verificar_tipos for each of them:

    def verifica(tuplas, tipos):
        for tupla in tuplas:
            if not verificar_tipos(tupla, tipos)
                return False
        return True
    

    You would use this:

    verifica([('paulo',19), ('maria',23),('joao',53)])
    
        
    06.11.2018 / 17:26