Criar uma função equivalente a porta AND e OR em python

Capturar

eu tentei fazer isso mas ele não verifica todos os elementos na lista.

def PortaAND(valores):
    if (len(valores) > 2):
        for i in range(len(valores) - 1):
            return 1 if (valores[i] and valores[i + 1] == 1) else 0
    else:
        return 1 if (valores[0] and valores[1] == 1) else 0 


def PortaOR(valores):
    if (len(valores) > 2):
        for i in range(len(valores) - 1):
           return 1 if (valores[i] or valores[i + 1] == 1) else 0
    else:
        return 1 if (valores[0] or valores[1] == 1) else 0

Na primeira iteração do for você já retorna, e o return sai da função (ou seja, quando a função encontra um return, a execução dela é interrompida e o valor é retornado). Por isso ele só verifica os dois primeiros elementos.

Mas a função não deveria receber somente dois valores (A e B)?

KKKKKKK tu é o carinha do stack overflow? KKKKK

bom, a porta and pode receber dois ou mais valores, acredito que a quantidade sempre é par

Não necessariamente. Se vc tiver A, B e C, e quiser fazer um A and B and C, daria também: seria o mesmo que fazer A and B, e depois pegar o resultado e fazer outro and com C.

A ideia básica seria (se for isso mesmo que vc quer fazer):

def PortaAND(valores):
    if len(valores) == 0: # se está vazio, é falso
        return 0
    res = valores[0] # pega o primeiro
    for i in valores[1:]: # faz o loop do segundo em diante
        if res == 1:
            res = i
    return res

Claro, assumindo que a lista só vai ter zeros e uns (não estou validando nada disso). A ideia de um AND é: se um elemento é 1, o resultado será 1 se o próximo também for 1, e zero se o próximo também for zero. Ou seja, se o elemento atual é 1, o resultado é o próximo elemento (é isso que esse if faz). Se o atual não for 1, é porque é zero, então o resultado será zero e por isso eu não preciso mudá-lo.


A ideia do OR é similar:

def PortaOR(valores):
    if len(valores) == 0: # se está vazio, é falso
        return 0
    res = valores[0]
    for i in valores[1:]:
        if res == 0:
            res = i
    return res

E claro que dá pra otimizar mais. Por exemplo, no AND, se algum elemento for zero o resultado já é zero, aí nem preciso verificar o resto (já poderia retornar zero direto). No OR é similar, se algum for 1 o resultado já será 1. Ex:

def PortaAND(valores):
    if len(valores) == 0: # se está vazio, é falso
        return 0
    for i in valores:
        if i == 0: # se for zero, o resultado já é zero, nem precisa ver o resto
            return 0
    return 1

nossa, muito obrigado kkk tava um tempão tentando. eu falei que é par pois no programa que tirei a print, são feitas comparações em pares de valores

Então, tem que ver se é isso ou se é o que eu disse acima, pois aí muda a forma de fazer…

então a forma é diferente kkkk o programa citado é o logisim

Complementando, uma forma mais simples:

def PortaAND(valores):
    return int(not (0 in valores))

def PortaOR(valores):
    return int(1 in valores)

No caso do AND, se tiver um zero, o resultado é zero. Eu uso o operador in para ver se o zero está na lista. Se estiver, eu nego com not para que seja False, e depois uso int, que converte o booleano para número (True é 1 e False é zero).

No caso do OR, a ideia é similar: se algum elemento for 1, o resultado é verdadeiro.

1 curtida

obrigadão