简体   繁体   中英

ValueError: math domain error from math.log but can't figure it out the error

I am trying to run the following code (from Fastest way to check if a value exist in a list ) by call profile():

but it seems that I got this error, ValueError: math domain error while my friend said he can run it without any issues. The expected result is a graph of three method.

I think the problem occurs at math.log which might depend on the random value.

time_method_in.append(math.log(method_in(a,b,c)))
time_method_set_in.append(math.log(method_set_in(a,b,c)))
time_method_bisect.append(math.log(method_bisect(a,b,c)))

I feel the error because the value is in negative value or were divide in too precise precision. So, I am trying to use log10 and decimal but none of those methods seem to work.

Is there anything I should try further? Thank you very much.

import random
import bisect
import matplotlib.pyplot as plt
import math
import time

def method_in(a,b,c):
    start_time = time.time()
    for i,x in enumerate(a):
        if x in b:
            c[i] = 1
    return(time.time()-start_time)   

def method_set_in(a,b,c):
    start_time = time.time()
    s = set(b)
    for i,x in enumerate(a):
        if x in s:
            c[i] = 1
    return(time.time()-start_time)

def method_bisect(a,b,c):
    start_time = time.time()
    b.sort()
    for i,x in enumerate(a):
        index = bisect.bisect_left(b,x)
        if index < len(a):
            if x == b[index]:
                c[i] = 1
    return(time.time()-start_time)

def profile():
    time_method_in = []
    time_method_set_in = []
    time_method_bisect = []

    Nls = [x for x in range(1000,20000,1000)]
    for N in Nls:
        a = [x for x in range(0,N)]
        random.shuffle(a)
        b = [x for x in range(0,N)]
        random.shuffle(b)
        c = [0 for x in range(0,N)]

        time_method_in.append(math.log(method_in(a,b,c)))
        time_method_set_in.append(math.log(method_set_in(a,b,c)))
        time_method_bisect.append(math.log(method_bisect(a,b,c)))

    plt.plot(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
    plt.plot(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
    plt.plot(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
    plt.xlabel('list size', fontsize=18)
    plt.ylabel('log(time)', fontsize=18)
    plt.legend(loc = 'upper left')
    plt.show()

Edit: As gazoh replied, I will use his work around for now. But I will revisit and update it again in future when I have more experience in Python and PyPlot. Thank you very much.

The first time method_in is called, it returns 0.0 when I tried to run your code, hence the error. You should implement a way to handle this case. Alternatively, you coud not compute the log of the values and use matplotlib's semilogy() to draw your plots in log scale:

plt.semilogy(Nls,time_method_in,marker='o',color='r',linestyle='-',label='in')
plt.semilogy(Nls,time_method_set_in,marker='o',color='b',linestyle='-',label='set')
plt.semilogy(Nls,time_method_bisect,marker='o',color='g',linestyle='-',label='bisect')
plt.xlabel('list size', fontsize=18)
plt.ylabel('time', fontsize=18)
plt.legend(loc = 'upper left')
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM