Find list trend if decrease over 80% - python

I have a dict like:
a = {'1': [100,95,10,80,82,78,8,7,9,2],
'2': [98,99,11,82,107,78,8,69,2],
'3': [10,98,10,80,20,45,46,50,4,2]}
If the list of trend drops below 80% and continues below 80% code will print "trend is under 80%". The last value of keys will be excluded.
For example In '1': [100,95,10,80,82,78,8,7,9,2] the last value is 2 so it will not be calculated.
Another example: In '1': [100,95,10,80,82,78,8,7,9] 100,95 drops over 80% to 10 and rises to 80 and continues around 80 and then drops to around 8. If this pattern is found in the code, it will write "value decreased under 80%".
To summarize, the value will drop over 80% and stability will continue under 80% till the end.
I can't use any library or define any function, only with if, else, for, while and something like that.

a = {'1': [100,95,10,80,82,78,8,7,9,2],
'2': [98,99,11,82,107,78,8,69,2],
'3': [10,98,10,80,20,45,46,50,4,2]}
for key, values in a.items():
below_80 = False
for value in values[:-1]:
if value < 80:
below_80 = True
elif below_80 and value >= 80:
print(f"Trend for {key} is under 80%")
break
if below_80:
print(f"Value for {key} decreased under 80%")
This code loops through each key-value pair in the dictionary a. For each value list, it checks if the values are below 80. If a value is below 80, it sets the flag below_80 to True. If below_80 is True and a value is equal or greater than 80, it prints "Trend for [key] is under 80%". After the inner loop, if below_80 is still True, it prints "Value for [key] decreased under 80%".

Related

Subtract from dict (python) until value is reached

I am new to using dict, and would like to subtract from the dict until I have reached a set value. The code for subtraction of a single value from a dict is this:
for k in dict_:
dict_[k] -= 1
Would it be possible to make this code only subtract data from a value in a dict if it is greater than a value that I set (for example 0)?
I think you're looking for something like this
threshold_val = 5 # say
for key, val in my_dict.items():
if val > threshold_val:
my_dict[key] = val - 1 # say we want to decrement by one
That should be pretty easy:
def foo(stop_val, subtraction_limit):
for k in dict_:
if k == stop_val:
break # exit loop
if dict_[k] > subtraction_limit:
dict_[k] -= 1
You should note that you have no control of the order in which the dictionary's keys are being iterated over. It might be different that the order in which you initiated the dictionary.
That means that iteration could stop at any point, and leave some values un-subtracted.
You can try something like this:
#example set value
set_value = 7
for k in d:
if (d[k] > set_value):
d[k] -= 1

Python 2.7: Add zeros to the size difference between lists of a multi-value dictionary and sum it

I have a multi-valued dictionary and I want to sum whatever the values are there which can be done with
for key, value in nai_dictionary.items():
nai_sum_rate.setdefault('%s' %(key), []).append(np.sum(rate_nai[key], axis=0))
for any nai_sum_rate dictionary, as suggested in this webpage. However, often times the length of the value lists is not the same.
This is the test data on which I'm testing right now
time = np.array([1,2,3,4,5,6])
test_dict['a'] = np.array([1,2,3,4,5,6]), np.array([1,2,3,4]), np.array([1,2,3,4,5,6])
What I want to do now, is to put a 0 in place of missing values for (in this case) the second array where there is no value against the time variable values and add them together.
In my previous testings, before the nai_sum_rate was a list instead of a dictionary I used the answer provided in this link to sort out the problem with the reference variable time. I've been trying with the dictionary but to no avail.
The expected sum is
3, 6, 9, 12, 10, 12
I solved the problem myself, here is the code that I came up with
for key, value in nai_dictionary.items():
i=0
while i < len(rate_nai[key]):
for key, value in nai_dictionary.items():
for index, values in enumerate(rate_nai[key]):
if len(time) < len(values):
diff = len(values) - len(time)
rate_nai[values] = values[0:np.array(values).size-diff]
elif len(time) > len(values):
diff = len(time) - len(values)
rate_nai['%s' %(key)].pop(index)
rate_nai.setdefault(
'%s' %(key)).append(np.append(np.array(values), np.zeros(diff)))
i+=1
It can tackle the problem with any number of values that have a lesser length than the reference variable time.

check if value is higher in dictionary

Right now i have this code:
keys = {
'key1':[5],
'key2':[2],
'key3':[3],
'key4':[2],
'key5':[1],
'key6':[2],
'key7':[9],
'key8':[10],
'key9':[8],
}
for i in keys:
print(keys[i])
the last prints all the values from the list
what i want to do is only print the key and the value if the value is bigger than 5
i cant just do
if keys[i] > 5:
that doesnt work
so does anybody know how i can check and write the key and value if the value is higher than 5?
That is because the values are arrays and not numbers. When working with an array you will need to specify the index for the value you want. In your case all your arrays only have one value, so the index you want each time is 0.
You can do this to check the first item in the array, it will also print the key:
for i in keys:
if keys[i][0] > 5:
print(i, keys[i])
Here is a working example
Of course it depends what you actually want to print. If you want to print the whole array:
print(i, keys[i])
If you want to print just the first value in the array:
print(i, keys[i][0])
Personally you should review what you actually want to work with, if your values are only ever going to be single integers, then you shouldn't really be using arrays at all and should define the collection differently:
keys = {
'key1':5
}
keys[i] is returning a list of numbers, not a single number. Either change your declaration to an int:
keys = {
'key1':5...
or change the line that compares it to pick the first entry in the 'keys' list:
if keys[i][0] > 5:
if you wanted to print the key name and it's value if this returns true, you would use:
if keys[i][0] > 5:
print i, keys[i][0]

Python max on potential same values

I have a problem with the max() function of python.
Here's my situation :
results = {'left' : leftKeyCounter, 'right' : rightKeyCounter, 'front' : frontKeyCounter, 'back' : backKeyCounter}
finalScore = max(results, key=results.get)
print(finalScore, 'wins')
The problem I have is to make if conditions on what's happening with my results. Let's say, I have
results = {'left' : 1, 'right' : 1, 'front' : 1, 'back': 0}
The fact that he will return 'front wins' on this is completely random, and I need to filter over that result. (or before?)
So that if it's a draw between the 2 highest results, that he cancels it (for example)
What could be the easiest way to make that possible ? I looked into the "counter" but that doesn't achieve what I intend to do here, as my numbers are already packed and I just need to compare 4 values, without any tie between the 2 highests value.
Thanks a lot ! :-)
With one pass over the dictionary you can figure out the correct result. Reverse the keys with the values and keep a track of the highest score. If there is more than one items for the highest score, you can return a custom message.
In reversing, you can't simply do {value: key for key, value in results.items()}, because if two values are the same, they will overwrite the previous one. So you have to keep the results in a list. Credits to chepner for scores.setdefault(). He also suggested that the same can be achieved with collections.defaultdict().
def calculate_winner(d):
scores = {}
high_score = 0
for key, value in d.items():
scores.setdefault(value, []).append(key)
if value > high_score:
high_score = value
results = scores[high_score]
if len(results) == 1:
return results[0]
else:
return 'TIE', results
Example:
>>> calculate_winner(results)
('TIE', ['front', 'right', 'left'])
Edit: If you have a small dictionary, you can achieve the same result with fewer lines of code by doing two passes: one to find the max score and one to filter out the winners.
def calcaluate_winner(d):
max_value = max(d.values())
winners = [key for key in d if d[key] == max_value]
if len(winners) == 1:
return winners[0]
else:
return 'TIE', winners

Read and add the last value from an array pulled from a text file

This is an example:
I have four time periods labeled as t=0, t=1, t=2, t=3. Each time has a value associated with it as shown below:
the format of the text file is as follows:
0,213
1,-999
2,456
3,-1100
Basically, each of the value is in one period.
What I want to do is to use those values and get all the values to t=0.
If I draw a timeline, then I would have two values on the positive at t=0 and t=2, and two values on the negative at t=1 and t=3.
Now, I want to go from the right hand side of the timeline to the left to get to t=0. So, at t=3, which is the last value in the timeline needs to move two units to the left to be added to the value of t=1 because they both are on the negative side, then finally move that value from t=1 to t=0. Similarly, I will need to do that for the positive side.
Following is my code. It may not be correct, but I am trying:
import numpy as np
workspace = 'C:\\Users\MM\Desktop'
time= np.loadtxt(workspace +'\\Assign1.txt', delimiter = ',', usecols = range(1))
value = np.loadtxt(workspace +'\\Assign1.txt', delimiter = ',', usecols = range(1,2))
for x in time:
x+1;
print(x)
for y in value:
y+1
print(y[-1])
# I want this to read the last value(-1100) from the array
# of the text file I have. I already got the values
# pulled from the text file. It gives me an error.
If I do get that to work, then since this is a negative value, I need to add that to the previous negative value, and so on.
The content I have is just a sample. There could be more or less than 4 time values, and the negative values and positive values could be anywhere on the timeline. The goal is to get the all the negative and positive values in t=0 and see if the negative values equals the positive values or not. The values needed to be considered equal if one of the values is greater by 1 but smaller than or equal to 15.
Algebraically, what you describe is much simpler than the process you've laid out. You add up all the numbers and see whether the result is in the range [-15, 15]. Replace your two intended loops with this conditional check:
if -15 <= sum(value) <= 15:
# Here, insert the code for matching stuff.
As for why your given code fails ... the loops are not correct. I'm not sure what you're trying to do with the two +1 expressions; they don't affect the data flow in any way, because you don't store the value.
The second loop is confused. In each iteration, you take a single value from the list. Your print statement treats that single value as if it were a list, too (you can make a list of lists in Python, but this program doesn't do that). When you try to access the last element of a single integer, Python informs you of the confusion.
To print the last value of the list, simply use print value[-1]; don't iterate through the entire list to find the last item.
That said, we now have the original problem: how to sum the negative and positive values using the algorithm you describe. You need to run your lists in the reverse order. I'll do this in two loops, one each for positive and negative:
time = range(10)
value = [213, -999, 456, -1100, -16, 5, 42, -80, 9, 10]
last_neg = 0
for i in range(len(value)-1, -1, -1): # Go through the list in reverse order
if value[i] < 0:
value[i] += last_neg
last_neg = value[i]
last_pos = 0
for i in range(len(value)-1, -1, -1): # Go through the list in reverse order
if value[i] > 0:
value[i] += last_pos
last_pos = value[i]
print "pos & neg sums", value[0], value[1]
value[0] += value[1]
print "grand sum", value[0]
print "Check the summation:", value
Output:
pos & neg sums 735 -2195
grand sum -1460
Check the summation: [-1460, -2195, 522, -1196, -96, 66, 61, -80, 19, 10]

Categories