Python multiplication using recursion without interactions of type `while` and `for`

Asked

Viewed 177 times

-3

I’m writing a multiplication calculator code that should use only arithmetic operators in the range of -10 >= x <= 10 and should always do the math under the best possible performance, ex.: 3x2 = 3 + 3 and not 3x2 = 2 + 2 + 2. My problem is that I cannot use the commands in any way while and for, I can only use the operators + and -. My idea was to do it first using while and for and then remove them, but I’m not seeing how that would be possible. Also, I need to print out the account intermediaries, for example: 3 x 10 I would have to print something similar to: 10; 20; 30 and I have no idea how to do that, maybe it’s something that opens up the possibility to be able to do without while and for, but I don’t know. I appreciate any help, I’m pretty tied up with this.

def erro_numero():
    print(' ')
    print('O número deve ser igual ou estar entre -10 e 10.')


def erro_letra():
    print(' ')
    print('O valor deve ser um número inteiro.')


def erro_0():
    print(' ')
    print('Não é possível dividir por zero.')


def primeiro_numero():
    try:
        x = int(input('Digite o valor do primeiro número: '))
        if x < -10 or x > 10:
            erro_numero()
            return primeiro_numero()
        else:
            return x

    except:
        erro_letra()
        return primeiro_numero()

def segundo_numero():
    try:
        z = int(input('Digite o valor do segundo número: '))
        if z < -10 or z > 10:
            erro_numero()
            return segundo_numero()
        else:
            return z
    except:
        erro_letra()
        return segundo_numero()


def produto(p, s):
    if p == 0 or s == 0:
        return 0
    else:
        sinal = True
        if (p < 0) != (s < 0):
            sinal = False

        if p < 0:
            p = 0 - p

        if s < 0:
            s = 0 - s

        resultado = 0
        if p > s:
            for i in range(s):           #Aqui o for e a função range() precisam ser removidas
                resultado = resultado + p
        else:
            for i in range(p):           #Aqui o for e a função range() precisam ser removidas
                resultado = resultado + s

        if sinal == False:
            return 0 - resultado
        else:
            return resultado


def print_do_valor(pro):          
    print('O valor do produto é:', pro)


while True:                   #Essa parte do código é só para fazer rodar
    p = primeiro_numero()
    s = segundo_numero()
    pro = produto(p, s)
    print_do_valor(pro)
  • 1

    it is possible to do "no while e for" - but it is not "healthy" - not if the intention of those who passed the exercise was to make you exercise a lot of "if" and "Elif" and copy paste code - but it is definitely not a good way to learn how to program - repetition structures are VERY fundamental in programming - and it is more important myth to master them than copy and paste code equal 10 times doing "if"s.

  • 1

    has a way that Xercises yes a good "think about programming" without for nem while, which is to simulate the loop using recursion. - if that is the intention at least does not get a lot of repetitions. Your teacher spoke in function and calling itself function?

  • He said yes, he said it should be done recursively, so much so that much of the code is written recursively. How, in this case, I would do to make the account and print the results using recursion?

1 answer

1


Clarified the doubts in the comment, you can write an answer that can be productive:

Being able to perform tasks repetitively is possibly the most important feature of digital computing. For example, just to "paint" the screen where this answer is being read, the computer is transferring the information of about 2 million pixels (~6 million bytes) between memory areas that represent the video buffer, and this 30 times per second (at least). Imagine doing it over and over again?

That said, the repeating structures that exist in all modern languages (in the case of Python while and for), are already abstractions on top of what the CPU actually "does" behind the scenes: all it does is conditional jumps - in the machine code the CPU subtracts a value from a number, and decides whether to jump to the execution to continue inside the loop or to continue forward, to another part of the programme.

Languages called "functional" - which subjectively we can say are closer to the coding used in modern mathematics, may not have "while" and "for", choosing to use the construction of "functions" - which all modern languages also have, and are extremely important, to represent also all repetitions.

This does not help to "learn python". It does not help to "learn programming" - but it helps to understand "what is possible to do with programming" and helps to better understand functions.

So first thing: forget the "print" part - what you need is to first calculate the multiplication value by calling functions. When you already have the calculated value, then yes, you print with only a "print".

So, what’s the idea of "repetition using recursion"? Simple - a function receives its parameters, and checks whether it has reached the end of the calculations it needs to do - if yes, returns the value found (). If not, make an interaction of the calculations - the equivalent of the code that would be in the body of a 'for' or 'while' and in the last line returns the value that itself returns, with the modified values, and indicating that one less interaction is missing to finish the process. When I arrive at the last interaction, that "return" I indicated with () goes through and through the "Return" of all previous calls.

There are two ways to write this, equivalent - one that looks more like a normal "for":

def multiplica(op1, contador, resultado_parcial=0):
    if contador == 0:
        return resultado_parcial
    resultado_parcial = resultado_parcial + op1
    return multiplica(op1, contador - 1, resultado_parcial)

And, refactoring a little, we have a form that becomes more "simple and elegant" and more similar to the use of functions in mathematics :

def multiplica(op1, op2):
    if op2 == 1:
        return op1
    return op1 + multiplica(op1, op2 - 1)

the result is exactly the same, and they are very similar, but in the latter the operation is done in the "inverse" order: the most "internal" sum is done before, and, at the time of return, one last operation is performed on each function call along the string. That is, in a multiplication of "4 X 3", after the third call with "4, 1", the Return line of the call with "4, 2" is executed, makes the sum of "4" with the internal result and returns to the outermost call "4, 3".

In Python this makes no difference - but in some functional languages, when there is no extra operation to be done with the return value of the recursive call (as written in the list above - the most internal returned value is only returned straightforward for those who called "multiply" for the first time), the language can make an optimization called "Tail call Optimization", in which all the information of the intermediate calls are "clean" - the last, more internal, Return already returns direct value to those who called "multiply" outsider.

In Python, recursive code is not very optimized - it’s easy to use when it improves readability, for example, to search for files in directory trees, or data in JSON structures of nested lists and dictionaries - but each recursive function call consumes 100 to 1000 times more computational resources than going back to the beginning of a "for" "while", creating an object called "Frame" with the state of the called function. So this kind of account is only good for teaching purposes.

Given the explanation, and how the mutiplication works, you should be able to finish your exercise: you have to deal with the negative operands, which I do not deal with above, nor with optimizing the execution to make fewer calls.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.