Home > Enterprise >  I have some problems with random module, lists and converting some variables
I have some problems with random module, lists and converting some variables

Time:07-06

I started recently working with Pyton 3.10 and while I was creating a graph that works with random data I got a problem. I want the random module work between a minimum and a maximum value but the random value have to oscillate in a range between - 0 to 0.10 compared to the previous value and so I had a problem to convert the list from the random.choices (named value) in a float number, i got this error "Expected type 'SupportsFloat | SupportsIndex | str | bytes | bytearray', got 'list[float]' instead" I know I can't convert a list in a float because a list is a set of numbers but searching on internet I found nothing to solve in others ways this problem. Can you please help me?

import random
import matplotlib.pyplot as plt
from itertools import count
from matplotlib.animation import FuncAnimation

minimo = 90.00
massimo = 110.00
altissimo = 108
alto = 104
basso = 96
bassissimo = 92
x_vals = []
y_vals = []
pmin = ()
pmag = ()
valori = [minore, maggiore]
index = count()
plt.plot(x_vals, y_vals)


def animate(i):
    global minore
    global maggiore
    global pmin
    global pmag

    value = random.choices(valori, weights=[pmin, pmag])
    print(value)
    value = float(value)     #<-- here is the problem
    value = round(value, 2)

    if value > altissimo:
        pmin = 80
        pmag = 20
    elif alto < value < altissimo:
        pmin = 60
        pmag = 40
    elif basso < value < alto:
        pmin = 40
        pmag = 60
    elif bassissimo < value < basso:
        pmin = 20
        pmag = 80

    delta = random.uniform(0, 0.10)
    delta = round(delta, 2)
    minore = value - delta
    maggiore = delta   value

    print(value)
    x_vals.append(next(index))
    y_vals.append(value)
    plt.cla()
    plt.plot(x_vals, y_vals)
    plt.tight_layout()


ani = FuncAnimation(plt.gcf(), animate, interval=10)
plt.tight_layout()
plt.show()

CodePudding user response:

Your fundamental misunderstanding, I think, is in this line:

valori = [minore, maggiore]

You seem to be expecting that random.choices will use that to choose between the current values of minore and maggiore. That's not how Python works. What that statement does is grab the current VALUE of those two variables. If you change minore after that, the valori list will not change.

I believe you are just using that array to choose whether to start with the minore or maggiore value, based on the percentages in pmin and pmag. There is an easier way to do that, just by checking whether random.random() produces a number above or below that.

And please eliminate all the calls to "round". Rounding is only to be used when you are presenting numbers for human consumption. Let the computer work with all the significant digits it can. Remember that "0.20" is still an approximation; it cannot be represented exactly in binary.

This minor change does what I think you want:

import random
import matplotlib.pyplot as plt
from itertools import count
from matplotlib.animation import FuncAnimation

altissimo = 108
alto = 104
basso = 96
bassissimo = 92
x_vals = []
y_vals = []
pmin = 0.50
index = count()
plt.plot(x_vals, y_vals)
minore = 99.0
maggiore = 101.0


def animate(i):
    global minore
    global maggiore
    global pmin

    value = minore if random.random() < pmin else maggiore
    print(value)

    if value > altissimo:
        pmin = .80
    elif value > alto:
        pmin = .60
    elif value > basso:
        pmin = .40
    elif value > bassissimo:
        pmin = .20

    delta = random.uniform(0, 0.10)
    minore = value - delta
    maggiore = value   delta

    print(value)
    x_vals.append(next(index))
    y_vals.append(value)
    plt.cla()
    plt.plot(x_vals, y_vals)
    plt.tight_layout()


ani = FuncAnimation(plt.gcf(), animate, interval=10)
plt.tight_layout()
plt.show()

CodePudding user response:

random.choices always returns a list. If you call it with the default k=1, it returns a list of 1 value. You could fix this in a couple of ways.

  1. On the line you marked as a problem, replace value = float(value) with value = float(value[0])

  2. Change the line where you call random.choices to: [value] = random.choices(valori, weights=[pmin, pmag]). That means that you expect random.choices to return a list of 1 item, and that you want to put that item (not the list) into the variable 'value'.

  • Related