Alex_Kazantsev
Alex_Kazantsev

Reputation: 157

A function with a generator and a print outputs a reference to an object

Looking for the roots of the equation by the dichotomy method: I have successfully implemented the method itself in Python code, but the essence of the question is different.

In the function I wrote myself, there is print() to output the roots. However, just like that, the function with the generator cannot be output - it only leads to a reference to the object. To see the roots in the console, I make an entry a list(function).

And in this case I get a double output of the roots: first in accordance with the implemented function, then in accordance with the list() notation.

How can I achieve the output of roots only in accordance with the method I wrote (with its rounding of the root and so on).

Code:

import numpy as np
import timeit
import time

def f(x):
    return 1.2-np.log(x)-4*np.cos(2*x)

def dichotomy (a,b,n, eps): # the segment from a to b is divided into n parts, the eps is error
    
    assert a!=0,  'a is 0'
    assert b!=0, 'b is 0'
    
    # first we separate the roots
    grid=np.linspace(a, b, n)
    
    # next , let 's clarify the roots
    for x,y in zip(grid, grid[1:]):
        if f(x) * f(y) > 0: 
            continue
        root = None
        while ( abs(f(y)-f(x)) )>eps:    
            mid = (y+x)/2                   
            if f(mid) == 0 or f(mid)<eps:    
                root = mid                  
                break
            elif (f(mid) * f(x)) < 0:       
                y = mid                     
            else:
                x = mid                     
        if root:
            yield root
            print(f'{root:.4f}', end=', ') # PRINT OUTPUT
    print()
    print(f'Time of the account: ', timeit.timeit('from __main__ import dichotomy'), 'seconds')

print(list(dichotomy(0.0001,184,10000, 0.000001))) # here the user substitutes the values of his arguments into the function and gets a printout of the roots, however, twice 

Upvotes: 0

Views: 169

Answers (1)

Alex_Kazantsev
Alex_Kazantsev

Reputation: 157

As a result of the discussion above, I implemented the code as follows (see below). The conclusion is as required:

Time of the account: 0.08493947982788086 seconds

The roots according to the dichotomy method are located at the points: 0.0645, 0.5527,...

The only problem that remains is the implementation of the timeit.timeit() method and passing parameters to it. In the given script, this issue is bypassed.

Code:

def print_dichotomy(dichotomy):
    def wrapper(a,b,n, eps):
        start_time = time.time()
        res = list(dichotomy(a,b,n, eps))
        print('Time of the account: %s seconds' % (time.time() - start_time))
        print('The roots according to the dichotomy method are located at the points: ')
        print(', '.join(map(lambda x: f'{x:.4f}', res)))
    return wrapper

@print_dichotomy
def dichotomy (a,b,n, eps): 
    
    assert a!=0,  'a is 0'
    assert b!=0, 'b is 0'
    
    # first we separate the roots
    grid=np.linspace(a, b, n)
    
    # next , let 's clarify the roots
    for x,y in zip(grid, grid[1:]):
        if f(x) * f(y) > 0: 
            continue
        root = None
        while ( abs(f(y)-f(x)) )>eps:    
            mid = (y+x)/2                   
            if f(mid) == 0 or f(mid)<eps:    
                root = mid                  
                break
            elif (f(mid) * f(x)) < 0:       
                y = mid                     
            else:
                x = mid                     
        if root:
            yield root

Upvotes: 1

Related Questions