9 Replies - 880 Views - Last Post: 15 April 2016 - 03:43 AM Rate Topic: -----

#1 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Read the value from column B and use the distribution function

Posted 11 April 2016 - 12:29 PM

Code below:

import random,xlrd
fileWorkspace = "/Users/Bob/Desktop/"

wb1 = xlrd.open_workbook(fileWorkspace + "Excel.xlsx")
sh1 = wb1.sheet_by_index(0)

dist,numbers = [],[]
for a in range(0,sh1.nrows):
    dist.append(str(sh1.cell(a,0).value))
    numbers.append(str(sh1.cell(a,1).value))
print(dist)
print(numbers)

if "expovariate" in dist:
    values = next((item.split(',') for item in numbers if item), None)
    ev_1 = [float(x) for x in values]
    ev = random.expovariate(ev_1)
    print(ev)


If the column has the word "expovariate" in it, then look the column next to it, and use that value to calculate the exporvariate value with that random.expovariate function. I have the if statement because I am doing the same thing for other distributions such as normalvariate, uniform, etc. They all work fine because they have two parameters that they take in, but expovariate only takes one, so that's where the problem comes in. So, keep all those lines in there or try to atleast.

Thanks!

Is This A Good Question/Topic? 0
  • +

Replies To: Read the value from column B and use the distribution function

#2 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 402
  • View blog
  • Posts: 1,297
  • Joined: 27-December 13

Re: Read the value from column B and use the distribution function

Posted 12 April 2016 - 07:31 AM

I don't really see a question here.
However, as 'ev_1' (line16) is a list you'll encounter an error in line 17.
As 'ev_1' only holds one element, you should try
ev = random.expovariate(ev_1[0])


If you want this to work also if numbers has more than one element (and thus value has the same), you can do a list unpacking:
ev = random.expovariate(*ev_1)


EDIT: I looked at this again; I don't understand why you use the 'values' list. You can do:
if "expovariate" in dist:
    ev_1 = [float(x) for x in numbers]  # skip 'values' and use 'numbers' directly
    ev = random.expovariate(*ev_1)  # use list unpacking
    print(ev)
This will also work with other distributions where two or more parameters are specified

This post has been edited by DK3250: 12 April 2016 - 12:25 PM

Was This Post Helpful? 1
  • +
  • -

#3 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 05:16 AM

View PostDK3250, on 12 April 2016 - 07:31 AM, said:

I don't really see a question here.
However, as 'ev_1' (line16) is a list you'll encounter an error in line 17.
As 'ev_1' only holds one element, you should try
ev = random.expovariate(ev_1[0])


If you want this to work also if numbers has more than one element (and thus value has the same), you can do a list unpacking:
ev = random.expovariate(*ev_1)


EDIT: I looked at this again; I don't understand why you use the 'values' list. You can do:
if "expovariate" in dist:
    ev_1 = [float(x) for x in numbers]  # skip 'values' and use 'numbers' directly
    ev = random.expovariate(*ev_1)  # use list unpacking
    print(ev)
This will also work with other distributions where two or more parameters are specified


Wow! Thanks a lot. I can't believe that one "*" could do the whole job. That was unbelievable.
Was This Post Helpful? 0
  • +
  • -

#4 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 05:23 AM

import random,xlrd
fileWorkspace = "/Users/Bob/Desktop/"

wb1 = xlrd.open_workbook(fileWorkspace + "Excel.xlsx")
sh1 = wb1.sheet_by_index(0)

dist,numbers = [],[]
for a in range(0,sh1.nrows):
    dist.append(str(sh1.cell(a,0).value))
    numbers.append(str(sh1.cell(a,1).value))
print(dist)
print(numbers)

if "random" in dist:
    values = next((item.split() for item in numbers if item), None)
    r_1 = [float(x) for x in values]
    r = random.random()
    print(r)


How do I take care of the code above. The only difference this has that instead of "expovariate", it has "random"
Was This Post Helpful? 0
  • +
  • -

#5 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 402
  • View blog
  • Posts: 1,297
  • Joined: 27-December 13

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 07:42 AM

My code in post #2 (omitting the 'values' list) will work here.
Your code fails because values == None - this leads to random.random(None) which is illegal; random.random(*[]) is ok.
I don't see the use of 'values' - can you skip it?

This post has been edited by DK3250: 13 April 2016 - 07:46 AM

Was This Post Helpful? 1
  • +
  • -

#6 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 08:59 AM

View PostDK3250, on 13 April 2016 - 07:42 AM, said:

My code in post #2 (omitting the 'values' list) will work here.
Your code fails because values == None - this leads to random.random(None) which is illegal; random.random(*[]) is ok.
I don't see the use of 'values' - can you skip it?


random.random(*[])
doesn't work. Yes, i took out the value line. Still the same error
IndexError: array index out of range

Was This Post Helpful? 0
  • +
  • -

#7 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 402
  • View blog
  • Posts: 1,297
  • Joined: 27-December 13

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 11:57 AM

Sure it works, try this:
>>> import random
>>> random.random(*[])
0.678377487391371
>>> 

Your error message (IndexError:...) is not related to the random function.
Please post your current version of the code and the full error message.
Was This Post Helpful? 1
  • +
  • -

#8 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 01:33 PM

Oh I see the error. This is the line they are pointing out to:
numbers.append(str(sh1.cell(a,1).value))


I can't remove that line if I have other distribution functions. You know what I mean. I understand there is nothing to append because there isn't anything to append. But, that only applies to "random" distribution. In the case of expovariate above and other cases like gammavariate,uniform,etc. I need that line

This post has been edited by Bob H.: 13 April 2016 - 01:37 PM

Was This Post Helpful? 0
  • +
  • -

#9 Bob H.  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 05-March 16

Re: Read the value from column B and use the distribution function

Posted 13 April 2016 - 03:54 PM

View PostDK3250, on 13 April 2016 - 11:57 AM, said:

Sure it works, try this:
>>> import random
>>> random.random(*[])
0.678377487391371
>>> 

Your error message (IndexError:...) is not related to the random function.
Please post your current version of the code and the full error message.


I got it. I modified the code elsewhere and it worked.
Was This Post Helpful? 0
  • +
  • -

#10 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 402
  • View blog
  • Posts: 1,297
  • Joined: 27-December 13

Re: Read the value from column B and use the distribution function

Posted 15 April 2016 - 03:43 AM

I couldn't resist generalizing the code a bit further. Take a look at this:
import random

## -- simulating data from some source -- ##
data = [
        ("random", []),
        ("expovariate", [0.02]),
        ("gauss", [2, 0.3])
        ]

my_data = random.choice(data)

dist = my_data[0]
number = my_data[1]
## -- end of simulation -- ##

res = eval("random." + dist + "(*number)")

print(dist, res)

The simulated data you (OP) read from Excel, but here I want a data set that everyone can follow.

The cornerstone here is the eval() function. With this you can "execute a string"
If fx the distribution is "gauss", you get to
res = eval("random.gauss(*number)")
As we have seen earlier, the list unpacking function(*<list>) will unpack the list into individual arguments.

You'll need to run this code a few times to see all three methods in action.

Maybe it's only me, but I like this form of generalized code. I hope others enjoy it as well.

This post has been edited by DK3250: 15 April 2016 - 03:48 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1