Name of List with maximum value - list

I am new to python. Using it with grasshopper.
I have 5 lists, each actually with 8760 items for which i have found max values at each index "but I also need to know which list the value came from at any given index."
I would put a simple example to explain myself better.
For 2 lists
A = [5,10,15,20,25]
B = [4,9,16,19,26]
Max value per index = [5,10,16,20,26]
What I want is something like
Max value per index = [5(A), 10(A), 16(B), 20(A), 26(B)]
Or something along the line that can relate. I am not sure whether its possible.
I would really appreciate the help. Thank you.

This can be adapted to N lists.
[(max(a),a.index(max(a))) for a in list(zip(A,B))]
The .index(max(a)) gets the index at which the max(a) occurs.
The output for your example is
[(5, 0), (10, 0), (16, 1), (20, 0), (26, 1)]
Of course, if both A and B share the same value, then the index will be the first one found, A.
See https://docs.python.org/3.3/library/functions.html for description of very useful zip built-in function.

Related

Adding values from multiple .rrd file

Problem =====>
Basically there are three .rrd which are generated for three departments.
From that we fetch three values (MIN, MAX, CURRENT) and print ins 3x3 format. There is a python script which does that.
eg -
Dept1: Min=10 Max=20 Cur=15
Dept2: Min=0 Max=10 Cur=5
Dept3: Min=10 Max=30 Cur=25
Now I want to add the values together (Min, Max, Cur) and print in one line.
eg -
Dept: Min=20 Max=60 Cur=45
Issue I am facing =====>
No matter what CDEF i write, I am breaking the graph. :(
This is the part I hate as i do not get any error message.
As far as I understand(please correct me if i am wrong) I definitely cannot store the value anywhere in my program as a graph is returned.
What would be a proper way to add the values in this condition.
Please let me know if my describing the problem is lacking more detail.
You can do this with a VDEF over a CDEF'd sum.
DEF:a=dept1.rrd:ds0:AVERAGE
DEF:b=dept2.rrd:ds0:AVERAGE
DEF:maxa=dept1.rrd:ds0:MAXIMUM
DEF:maxb=dept2.rrd:ds0:MAXIMUM
CDEF:maxall=maxa,maxb,+
CDEF:all=a,b,+
VDEF:maxalltime=maxall,MAXIMUM
VDEF:alltimeavg=all,AVERAGE
PRINT:maxalltime:Max=%f
PRINT:alltimeavg:Avg=%f
LINE:all#ff0000:AllDepartments
However, you should note that, apart form at the highest granularity, the Min and Max totals will be wrong! This is because max(a+b) != max(a) + max(b). If you dont calculate the min/max aggregate at time of storage, the granularity will be gone at time of display.
For example, if a = (1, 2, 3) and b = (3, 2, 1), then max(a) + max(b) = 6; however the maximum at any point in time is in fact 4. The same issue applies to using min(a) + min(b).

Prolog List Neighbour of a Element

I am having problems with list of prolog. I want to make this:
[1,2,3,4,5]
[5,6,9,12,10]
You take a number for example 3, and you do a plus operation with the neighbours so the operation is 2+3+4 = 9. For the first and the last element you pretend there is an imaginary 1 there.
I have this now:
sum_list([A,X,B|T], [Xs|Ts]):-
add(A,X,B,Xs),
sum_list([X,B|T], Ts).
I haven't consider the first and the last element. My problem is I don't know how to get the element before and the next and then how to move on.
Note: I not allow to use meta-predicates.
Thanks.
I'm not sure how you calculated the first 5. The last 10 would be 4 + 5 + implicit 1. But following that calculation, the first element of your result should be 4 instead of 5?
Anyways, that doesn't really matter in terms of writing this code. You are actually close to your desired result. There are of course multiple ways of tackling this problem, but I think the simplest one would be to write a small 'initial' case in which you already calculate the first sum and afterwards recursively calculate all of the other sums. We can then write a case in which only 2 elements are left to calculate the last 'special' sum:
% Initial case for easily distinguishing the first sum
initial([X,Y|T],[Sum|R]) :-
Sum is X+Y+1,
others([X,Y|T],R).
% Match on 2 last elements left
others([X,Y],[Sum|[]]) :-
Sum is X+Y+1.
% Recursively keep adding neighbours
others([X,Y,Z|T],[Sum|R]) :-
Sum is X+Y+Z,
others([Y,Z|T],R).
Execution:
?- initial([1,2],Result)
Result = [4,4]
?- initial([1,2,3,4,5],Result)
Result = [4, 6, 9, 12, 10]
Note that we now don't have any cases (yet) for an empty list or a list with just one element in it. This still needs to be covered if necessary.

How to add sequential numbers to a list of tuples

I have a question which looks quite simple, but I could not find an acceptable answer as yet. It looks that variations of it have already been asked here several times, but none of the answers was helpful to me.
Here it is:
I have a lists of tuples, as follows:
reflist = [("Author1", 1900, "Some reference"), ("Author2", 1901, "Another reference"), ("Author3", 1902, "Yet another reference")]
What I want is to add a sequential number to each tuple in the list, so that I got:
reflist = [(1, "Author1", 1900, "Some reference"), (2, "Author2", 1901, "Another reference"), (3, "Author3", 1902, "Yet another reference")]
This looks silly and a list comprehension should do the trick, but I cannot discern just how :-(
Thanks in advance for any assistance you can provide.
enumerate() runs over a sequence and generates index, value pairs. You can't merge directly into your tuples - because tuples are immutable, you can't change their length - but one way you could do it is to convert the tuples you have into lists, make the index number a list, concatenate the two lists together, and convert the result to a tuple:
reflist2 = [tuple([index+1] + list(ref)) for index, ref in enumerate(reflist)]
(I've edited it to index+1 because enumerate starts counting from 0)
f = [tuple(list(elem).insert(0, i)) for elem in reflist for in range(len(reflist))]
What this list comprehension does is that it tells for each original entry in reflist, it should convert it to a list, then insert a number in some integer list to the 0 position of the list, then convert that list back into a tuple, and put it all together in a ne wlist.

Summing the first value in each tuple in a list over a specific range in Python

My question is based on an earlier question and I can't find to figure out (nor find) the subsequent step I need.
Say I do have the same list of tuples, namely:
[(0, 1), (2, 3), (5, 7), (2, 1)]
Also I wish to find the sum of the first values in each pair, which could be done by the simple pythonic:
sum([pair[0] for pair in list_of_pairs])
as provided by David Z. However, in my case I only wish to sum from the first first value up until a following first value, say the first value at index N = 2.
Thus, only calculate the sum of:
0 + 2 + 5
I have been trying things like:
sum([pair[0] for pair in list_of_pairs[:N])
but without success. Can anyone provide me with an elegant solution?
you were very close to the solution
This works for me :
N=2
sum([pair[0] for pair in list_of_pairs[0:N+1]])
If you wants from middle then you can do this :
N=3
M=1
print sum([pair[0] for pair in list_of_pairs[M:N+1]])

Time based rotation

I'm trying to figure out the best way of doing the following:
I have a list of values: L
I'd like to pick a subset of this list, of size N, and get a different subset (if the list has enough members) every X minutes.
I'd like the values to be picked sequentially, or randomly, as long as all the values get used.
For example, I have a list: [google.com, yahoo.com, gmail.com]
I'd like to pick X (2 for this example) values and rotate those values every Y(60 for now) minutes:
minute 0-59: [google.com, yahoo.com]
minute 60-119: [gmail.com, google.com
minute 120-179: [google.com, yahoo.com]
etc.
Random picking is also fine, i.e:
minute 0-59: [google.com, gmail.com]
minute 60-119: [yahoo.com, google.com]
Note: The time epoch should be 0 when the user sets the rotation up, i.e, the 0 point can be at any point in time.
Finally: I'd prefer not to store a set of "used" values or anything like that, if possible. i.e, I'd like this to be as simple as possible.
Random picking is actually preferred to sequential, but either is fine.
What's the best way to go about this? Python/Pseudo-code or C/C++ is fine.
Thank you!
You can use the itertools standard module to help:
import itertools
import random
import time
a = ["google.com", "yahoo.com", "gmail.com"]
combs = list(itertools.combinations(a, 2))
random.shuffle(combs)
for c in combs:
print(c)
time.sleep(3600)
EDIT: Based on your clarification in the comments, the following suggestion might help.
What you're looking for is a maximal-length sequence of integers within the range [0, N). You can generate this in Python using something like:
def modseq(n, p):
r = 0
for i in range(n):
r = (r + p) % n
yield r
Given an integer n and a prime number p (which is not a factor of n, making p greater than n guarantees this), you will get a sequence of all the integers from 0 to n-1:
>>> list(modseq(10, 13))
[3, 6, 9, 2, 5, 8, 1, 4, 7, 0]
From there, you can filter this list to include only the integers that contain the desired number of 1 bits set (see Best algorithm to count the number of set bits in a 32-bit integer? for suggestions). Then choose the elements from your set based on which bits are set to 1. In your case, you would use pass n as 2N if N is the number of elements in your set.
This sequence is deterministic given a time T (from which you can find the position in the sequence), a number N of elements, and a prime P.