Vse o Programiranju 1 - PRM 2021/22

type in isinstance

type in isinstance

by Matija Lokar -
Number of replies: 0

S štefanom sva imela razgovor glede težav pri reševanju tretje podnaloge pri SSCŠ se vrača v sklopu Rekurzija II. Dobro je, da to zveste tudi vi in se naučite nekaj o type in isinstance. 

Težava je bila, ker je test  
      koliko_napacnih([False, 3, True]) 

vračal 0! Koda je bila 

def koliko_napacnih(sscs):
    '''Vrne koliko elementov v SSCS ni pravilnih'''
    if je_sscs(sscs):
        return 0
    if not(isinstance(sscs,list)):
        return None
    skupaj=0
    for elt in sscs:
        if isinstance(elt, int):
            continue      
        if not je_sscs(elt) or isinstance(elt,bool):
            skupaj += 1
    return skupaj
Problem je bil dejansko v 

        if isinstance(elt, int):
            continue
Namreč  isinstance(True, int) ali isinstance(False, int)  nam vrne True!!  

Če torej ta stavek spremenimo v 

        if isinstance(elt, int) and not isinstance(elt, bool):
            continue
zadeva dela. Seveda lahko zadevo napišemo tudi kot 

def koliko_napacnih(sscs):
    '''Vrne koliko elementov v SSCŠ ni
       pravilnih, torej niso cela števila ali pa SSCŠ
    '''
    if not(isinstance(sscs,list)):
        return None
    skupaj=0
    for elt in sscs:
        if isinstance(elt, int) and not isinstance(elt, bool):
            continue
        koliko_nar = koliko_napacnih(elt)
        if koliko_nar is None or koliko_nar > 0:
            skupaj += 1
    return skupaj
ali pa 

def koliko_napacnih(sscs):
    '''Koliko elementov je v sscs napačnih'''
    if not isinstance(sscs, list):
        return None
    koliko_narobe = 0
    # pregledamo vse elemente
    for el in sscs:
        if (not isinstance(el, int)) and (not je_sscs(el)) \
                or isinstance(el, bool):
                koliko_narobe += 1
    return koliko_narobe

ali pa ...

Torej ključna težava je v tem, da   isinstance(elt, int)  na logičnih vrednostih vrne True!  
Torej bi bilo bolje uporabiti type, ki se pa obnaša "prav"

>>>  type(False) is int
False
>>>  type(False) is bool
True
>>>  type(True) is int
False
>>>  type(True) is bool
True
Torej "najboljša" rešitev bi bila 

def koliko_napacnih(sscs):
    '''Vrne koliko elementov v SSCŠ ni
       pravilnih, torej niso cela števila ali pa SSCŠ
    if not(isinstance(sscs,list)):
        return None
    skupaj=0
    for elt in sscs:
        if type(elt) is int:
            continue
        if not je_sscs(elt):
            skupaj += 1
    return skupaj

Mimogrede, zakaj pa potem imeti isinstance ... Hm, isinstance zna sočasno preverjati, ali je tip  nekaj med večimi tipi  (npr.

isinstance(x, (int, float, complex) 
kar bi morali s type napisati 

type(x) is float or type(x) is float or type(x) is complex) 
preveri, ali je nekaj poljubno število, prav tako pa se obnaša "prav" pri objektnem programiranju z dedovanjem.