Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generating 10 values in python around one value

I am trying do write a quick simulation program. As a first step, I want to take an input and do the following:

  1. Use this input to find the corresponding value from the dict, say I got 29.0 in my example.
  2. I would now like to generate 3 values to the left and 3 values to the right. Ideally the output should be 27.5, 28.0, 28.5, 29.0, 29.5, 30, 30.5

Here is my program -- which is partially solving my problem.

#!/usr/bin/python
def getids(tk):
    tk=tk.lower()
        r=map(lambda x:x/10.0,range(0,6))   
    val={'PPP':29}
    val={k.lower():v for k,v in val.items()}
    if tk in val:
        stk_price=val[tk]   
    for i in r:
        stk_price=stk_price + i
        print(stk_price)
getids('PPP')

The output is

29.0
29.1
29.3
29.6
30.0
30.5

Is it possible to use numpy and generate values around a number ? Appreciate any help.

like image 820
Judi Avatar asked Apr 06 '18 15:04

Judi


People also ask

How do I make a list between two numbers in Python?

Use range() to create a list of numbers between two values. Call range(start, stop) to construct a sequence of numbers. The sequence ranges from start up to but not including stop . Use list() to convert this sequence to a list.


4 Answers

First a couple of notes on design:

  1. Your dictionary should live outside the function, otherwise it gets recreated every time, which is fairly pointless and inefficient.
  2. If you have a function to get a range, make it return the range. If you want to print the range or do something else with it, do that outside the function.

You are probably looking for either np.arange or np.linspace. For your simple application, they are essentially equivalent. This is especially true because there is no roundoff error when stepping with an increment of 0.5.

For a given x, say 29, you could do either of the following:

step = 0.5
price_range = np.arange(x - step * 3, x + step * 4, step)

OR

step = 0.5
price_range = np.linspace(x - step * 3, x + step * 3, 7)

Personally I find linspace easier to understand here, because you just give it the limits and the number of points. For arange, you have to remember that the stop is exclusive, so you have to add a margin to x + step * 3.

I would recommend rephrasing your program like this:

stocks = {
    'PPP': 29,
}
# Notice that this only runs once instead of once per function call now
# casefold is the more generalized unicode version of lower
stocks = {key.casefold: value for key, value in stocks}

def getids(tk, margin=3, step=0.5):
    tk = tk.casefold()
    if tk in val:
        price = val[tk]
        return np.linspace(price - margin * step,
                           price + margin * step, 2 * margin + 1)
    return []

print(getids('PPP'))

If you want the exact output you had before, just join the elements with newlines:

print('\n'.join(map(str, getids('PPP'))))

or equivalently,

print('\n'.join(str(x) for x in getids('PPP')))
like image 152
Mad Physicist Avatar answered Oct 28 '22 21:10

Mad Physicist


You can use arange function of numpy.

Minimal example:

import numpy as np

num = 29    
np.arange(num-1.5, num+2, 0.5) # (start, stop, step)

The output will be

array([ 27.5,  28. ,  28.5,  29. ,  29.5,  30. ,  30.5])
like image 43
Giorgos Myrianthous Avatar answered Oct 28 '22 21:10

Giorgos Myrianthous


Very similar to np. arange, with np.linspace, you can get an array of evenly spaced values, of whatever length you want. So, in your case, to get 3 values on the left and 3 values to the right (+1 to include your actual value), you'll want a total of 7 values. You can get them like this:

import numpy as np

x = 29
np.linspace(x-1.5, x+1.5, 7) #start, stop, number of values

# array([ 27.5,  28. ,  28.5,  29. ,  29.5,  30. ,  30.5])
like image 3
sacuL Avatar answered Oct 28 '22 20:10

sacuL


Disclaimer: Not a numpy solution, but plain old python.

You can generate them using a combination of range / delta and steps around a piveau value:

def getSeries(piv, nums, delta):
    """Yields [piv + (-nums * delta):piv + nums * delta] in steps of delta"""
    for k in range(-nums,nums+1):
       yield piv + k*delta

for n in getSeries(29,3,0.5):
    print(f'{n:.1f}')

Output:

27.5  # -3
28.0  # -2
28.5  # -1
29.0  # piveau
29.5  #  1
30.0  #  2
30.5  #  3
like image 2
Patrick Artner Avatar answered Oct 28 '22 21:10

Patrick Artner