Find sequences of minimum 3 values that differ only by 0.5% - python-3.x

lets say I have a list like [1,2,1.5,2,1.99,2.01,4] and I want my function to find the sequence [2,1.99,2.01] and build a new list of it. This can happen multiple times while looping over the initial list. I hope my problem is understandable.
Thanks in advance
This is my attempt:
import itertools
Support = []
Liste1 = [1,2,1.5,2,1.99,2.01,4]
Liste2 = Liste1[1:]
Liste1.pop(-1)
for S1,S2 in itertools.zip_longest(Liste1, Liste2):
if S2<=1.05*S1 and S2>=0.95*S1:
Support.append(S1)
The problem is that this loop will compare the value to the value before and not to the first value which was detected as the start of a series.

Layer1 = [round(x,2) for x in list(data["Close"])]
Layer2 = Layer1[0:1]
Layer1.pop(0)
Layer3 = []
Layer4 = []
for element in Layer1:
if element < 1.01*Layer2[0] and element > 0.99*Layer2[0]:
Layer2.append(element)
if len(Layer2)>= 6:
Layer3.extend(Layer2)
Layer4.append(statistics.mean(Layer3))
Layer3.clear()
Layer2.clear()
Layer2.append(element)
else:
Layer2.clear()
Layer2.append(element)
R_S = sorted([round(s,2) for s in Layer4])
R_S_clean = R_S[0:1]
R_S.pop(0)
for element in R_S:
if element >= 1.01*R_S_clean[-1] or element <= 0.99*R_S_clean[-1]:
R_S_clean.append(element)
R_S_clean_rev = reversed(R_S_clean)
for element in R_S_clean_rev:
if element < Price:
Support = element
Delta_S = str(abs(round((100-((100/element)*Price)),2))) + "%"
break
else:
Support = "/"
Delta_S = "/"
for element in R_S_clean:
if element > Price:
Resistance = element
Delta_R = str(abs(round((100-((100/element)*Price)),2))) + "%"
break
else:
Resistance = "/"
Delta_R = "/"
This is my workaround, time will tell if the performance is good enough.

Related

Is there any way to replace for loop to Multiple-threading for speedy time execution?

For a detailed understanding, I have attached a link of file.
Indetail understanding code
I have data in the list, that has similar syntax like:
i = [a.b>c.d , e.f.g>h.i.j ]
l = [a.b , e.f.g ]
n = [a.b>c.d , e.f.g ]
e.g. Each element of the list has multiple sub-elements separated by "." and ">"
for i in range(0, len(l)):
reac={}
reag={}
t = l[i].split(">")
REAC = t[0]
Reac = REAC.split(".")
for o in range(len(Reac)):
reaco = "https://ai.chemistryinthecloud.com/smilies/" + Reac[o]
respo = requests.get(reaco)
reac[o] ={"Smile":Reac[o],"Details" :respo.json()}
if (len(t) != 1):
REAG = t[1]
Reag = REAG.split(".")
for k in range(len(Reag)):
reagk = "https://ai.chemistryinthecloud.com/smilies/" + Reag[k]
repo = requests.get(reagk)
reag[k] = {"Smile": Reag[k], "Details" :repo.json()}
res = {"Reactants": list(reac.values()), "Reagents": list(reag.values())}
boo.append(res)
else:
res = {"Reactants": list(reac.values()), "Reagents": "No reagents"}
boo.append(res)
We have separated all the elements and for each element, we are calling 3rd party API. That consumes too much time.
Is there any way to reduce this time and optimize for the loop?
It takes around 1 minute to respond. We want to optimize to 5-10 seconds.
You can start multiple requests and process them when they are finished with
ThreadPoolExecutor.
That might speed it up a bit.

How to shuffle two strings to a set of string in Python3

How can I shuffle two strings s||t (shuffle(s, t)) with the given requirement that the first char always stands in front of the second one in s and t as well no matter we shuffle. The result returns as a set of strings without duplicates.
I have the following test:
print(shuffle('ab', 'cd'))
Result:
['abcd', 'acbd', 'acdb', 'cabd', 'cadb', 'cdab']
Thanks a lot.
This method will shuffle two strings and return a list of shuffles between them where the order of the characters is the same as in the original strings. If there are duplicate characters there will be duplicate results as well.
def shuffle(s1, s2):
if len(s1) == 1:
return [s2[:i] + s1 + s2[i:] for i in range(len(s2) + 1)]
if len(s2) == 1:
return [s1[:i] + s2 + s1[i:] for i in range(len(s1) + 1)]
return [s1[0]+ s for s in shuffle(s1[1:], s2)] + [s2[0] + s for s in shuffle(s1, s2[1:])]
print shuffle("ab", "cd")
It works by getting the first character of each string and recursively shuffling the rest and adding this character to each element in the list. When there is one character remaining on each of the strings it returns a list where the character is added in each position of the other string. Hope it helps.
So you can apply a condition on final shuffled list to generate a new list from the shuffled one:
S=shuffle('ab','cd')
nl=[]
for w in S:
if(w.index('a')<w.index('b') and w.index('c')<w.index('d')):
nl.append(w)
So nl is your new list as per your requirement:)
If I understood the question correctly, this should work. Note, as you add letters to this, it becomes a long running problem. 4 letters have 6 possible combination for each entry in the list. 8 letters have 5,040 possible combinations for each entry in the list.
import random
import math
InputList = ['ab','cd']
PossibleUniqueCombinations = math.factorial(len("".join(InputList))-1)
print (PossibleUniqueCombinations)
TargetList = []
UniqueCombinationList = []
for lst in InputList:
UniqueCnt = 0
FirstChar = lst[0]
TheRest = list(lst[1:])
while UniqueCnt < PossibleUniqueCombinations:
if InputList.index(lst) == 0:
LeftList = []
else:
LeftList = InputList[0:InputList.index(lst)]
RightList = list(InputList[InputList.index(lst)+1:])
TargetList = LeftList + TheRest + RightList
TargetStr = ''.join(TargetList)
TargetStr = ''.join(random.sample(TargetStr, len(TargetStr)))
ShuffledStr = FirstChar + ''.join(TargetStr)
try:
FndIdx = UniqueCombinationList.index(ShuffledStr)
except ValueError:
UniqueCombinationList.append(ShuffledStr)
UniqueCnt += 1
for combo in UniqueCombinationList:
print(combo)

TypeError: 'int' object is not iterable when calculating mean

I am trying to read different values from a file and to store them in a list. After that, I need to take their mean and in doing so I am getting the error above. Code is working up to to line
"Avg_Humidity.append(words[8])"
Here it is:
def monthly_report(path,year,month):
pre_script="Murree_weather"
format='.txt'
file_name = pre_script + year + month+format
name_path=os.path.join(path,file_name)
file = open(name_path, 'r')
data = file.readlines()
Max_Temp = []
Min_Temp = []
Avg_Humidity = []
for line in data:
words = line.split(",")
Max_Temp.append(words[1])
Min_Temp.append(words[3])
Avg_Humidity.append(words[8])
Count_H, Count_Max_Temp, Count_Min_Temp, Mean_Max_Temp, Mean_Min_Temp,
Mean_Avg_Humidity=0
for iterate in range(1,len(Max_Temp)):
Mean_Max_Temp= Mean_Max_Temp+Max_Temp(iterate)
Count_Max_Temp=Count_Max_Temp+1
Mean_Max_Temp=Mean_Max_Temp/Count_Max_Temp
for iterate in range(1,len(Min_Temp)):
Mean_Min_Temp= Mean_Min_Temp+Min_Temp(iterate)
Count_Min_Temp=Count_Min_Temp+1
Mean_Min_Temp=Mean_Min_Temp/Count_Min_Temp
for iterate in range(1,len(Avg_Humidity)):
Mean_Avg_Humidity= Mean_Avg_Humidity+Avg_Humidity(iterate)
Count_H=Count_H+1
Mean_Avg_Humidity=Mean_Avg_Humidity/Count_H
print("Mean Average Humidity = ",Mean_Avg_Humidity)
print("Mean Maximum Temperature = ",Mean_Max_Temp)
print("Mean Minimum Temperature = ",Mean_Min_Temp)
return
This line is incorrect:
Count_H, Count_Max_Temp, Count_Min_Temp, Mean_Max_Temp, Mean_Min_Temp, Mean_Avg_Humidity = 0
To fix, change it to:
Count_H = Count_Max_Temp = Count_Min_Temp = Mean_Max_Temp = Mean_Min_Temp = Mean_Avg_Humidity = 0
An alternative fix would be to leave the commas as they are and change the right-hand side to a list or tuple of zeroes that has the same number of elements as the left-hand side. But that would be less clear, and harder to maintain.

How can I generate a list starting with the first value in a range?

I have a string that indicates a range of values: "A1C - A1H"
I need to be able to create a list of all the values in that range, meaning: ['A1C', 'A1D', 'A1E', 'A1F', 'A1G', 'A1H']
list = []
range = "A1C - A1H"
code = range[:2]
range_end = range[-3:]
for letter in ascii_uppercase:
order = code+letter
if order not in range_end:
list.append(order)
else:
list.append(range_end)
break
print(list)
The code runs, as is but it creates a list with the first 'A1A', 'A1B' values which I don't need:
['A1A', 'A1B', 'A1C', 'A1D', 'A1E', 'A1F', 'A1G', 'A1H']
How can I generate the list starting with 'A1C'?
Start the "for letter in ascii_uppercase" two char later
list = []
range = "A1C - A1H"
code = range[:2]
range_end = range[-3:]
count = 0
for letter in ascii_uppercase:
if count > 1:
order = code+letter
if order not in range_end:
list.append(order)
else:
list.append(range_end)
break
count += 1
print(list)
You can use the built-in ord and chr functions with a list comprehension instead to generate the desired list:
l = ['A1' + chr(i) for i in range(ord('C'), ord('H') + 1)]
l would become:
['A1C', 'A1D', 'A1E', 'A1F', 'A1G', 'A1H']
You can compare letter code and start loop when it is greater than starting point of string :
import string
def generate(string_data):
code = string_data[:2]
range_end = string_data[-3:]
sub_range = string_data[2:-6]
result=[]
for letter in string.ascii_uppercase:
if ord(letter)< ord(sub_range):
pass
elif code+letter == range_end:
result.append(code+letter)
break
else:
result.append(code+letter)
return result
output:
['A1C', 'A1D', 'A1E', 'A1F', 'A1G', 'A1H']
alternative solution:
This is not best solution but you can also slice the list from list in your code:
list_data = []
range_data = "A1C - A1H"
code = range_data[:2]
range_end = range_data[-3:]
for letter in string.ascii_uppercase:
order = code+letter
if order not in range_end:
list_data.append(order)
else:
list_data.append(range_end)
break
print(list_data[list_data.index(range_data[:3]):list_data.index(range_end)+1])
Note: Don't use list and range as variable name , They have special meaning in Python.

python3 Why does max( listOfStrings) not return the longest element? [duplicate]

I have a list of variable length and am trying to find a way to test if the list item currently being evaluated is the longest string contained in the list. And I am using Python 2.6.1
For example:
mylist = ['abc','abcdef','abcd']
for each in mylist:
if condition1:
do_something()
elif ___________________: #else if each is the longest string contained in mylist:
do_something_else()
Surely there's a simple list comprehension that's short and elegant that I'm overlooking?
From the Python documentation itself, you can use max:
>>> mylist = ['123','123456','1234']
>>> print max(mylist, key=len)
123456
def longestWord(some_list):
count = 0 #You set the count to 0
for i in some_list: # Go through the whole list
if len(i) > count: #Checking for the longest word(string)
count = len(i)
word = i
return ("the longest string is " + word)
or much easier:
max(some_list , key = len)
What should happen if there are more than 1 longest string (think '12', and '01')?
Try that to get the longest element
max_length,longest_element = max([(len(x),x) for x in ('a','b','aa')])
And then regular foreach
for st in mylist:
if len(st)==max_length:...
To get the smallest or largest item in a list, use the built-in min and max functions:
lo = min(L)
hi = max(L)
As with sort, you can pass in a "key" argument that is used to map the list items before they are compared:
lo = min(L, key=int)
hi = max(L, key=int)
http://effbot.org/zone/python-list.htm
Looks like you could use the max function if you map it correctly for strings and use that as the comparison. I would recommend just finding the max once though of course, not for each element in the list.
len(each) == max(len(x) for x in myList) or just each == max(myList, key=len)
def LongestEntry(lstName):
totalEntries = len(lstName)
currentEntry = 0
longestLength = 0
while currentEntry < totalEntries:
thisEntry = len(str(lstName[currentEntry]))
if int(thisEntry) > int(longestLength):
longestLength = thisEntry
longestEntry = currentEntry
currentEntry += 1
return longestLength

Resources