How to count the weeks between specific week numbers? - python

I Have the below data format.It is a dictionary with names as keys, and a list of week numbers as values.
{'Mali': [17, 16, 23, 18, 17, 16, 17, 18, 16],
'Gooki': [7, 8, 8, 15, 7, 7, 8],
'Piata': [85],
'Goerge': [82],
'Samoo': [106, 55],
'Marria: [101,39]}
I would like to count the number of weeks between the week numbers, and change the value of dictionary with the number of weeks instead of week numbers.This means that for instance in name 'Samoo' I have week 55 and week 106. I would like my code to count these two weeks plus the weeks between them(which is equal to 52 weeks ) and set it as the value for dictionary.
I have the below code, but I am not sure to make this above count.
datedict = defaultdict(set)
with open('d:/info.csv', 'r') as csvfile:
filereader = csv.reader(csvfile, 'excel')
#passing the header
read_header = False
start_date=date(year=2009,month=1,day=1)
#print((seen_date - start_date).days)
tdict = {}
for row in filereader:
if not read_header:
read_header = True
continue
# reading the rest rows
name,firstseen = row[0],row[3]
try:
seen_date = datetime.datetime.strptime(firstseen, '%d/%m/%Y').date()
deltadays = (seen_date-start_date).days
deltaweeks = deltadays/7 + 1
key = name
currentvalue = tdict.get(key, set())
currentvalue.add(deltaweeks)
tdict[key] = currentvalue
except ValueError:
print('Date value error')
pass
pprint.pprint(tdict)
Can anyone help me with this?

>>> d = {'Mali': [17, 16, 23, 18, 17, 16, 17, 18, 16],
'Gooki': [7, 8, 8, 15, 7, 7, 8],
'Piata': [85],
'Samoo': [47, 63, 48, 58, 49, 48],
'Goerge': [82],
'Samoo': [106, 55],
'Marria': [101,39]}
>>> dict((name, max(weeks) - min(weeks) + 1) for name, weeks in d.iteritems())
{'Samoo': 52, 'Gooki': 9, 'Mali': 8, 'Goerge': 1, 'Piata': 1, 'Marria': 63}

Related

Append list to a row

I have List Called my_list have series of No I want add that no to a excel's perticuler row
I want list's No start from E2 to len(my_list)
And row is a single and start from E2 to AH2
elements will place in E2 to AH2 likewise image
Click On Here To see Image
wb = load_workbook("Myworkbook.xlsx")
ws = wb.active
my_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
for rw in ws['E2:AH2']:
for cell in rw:
for c in my_list:
cell.value = c
wb.save('Myworkbook.xlsx')
But In this way I just get last element of list like in image it gives only 31 but i want 1 to 31
in range and append in particularly in that single row
Click On Here To See image
This is because your last loop (over my_list) goes through the entire list, up to 31, for each cell of your row. That's why you end up with the last value in every cell. You have nested this loop too deep.
What you actually want is go through each cell and value at the same time. Simplest way to achieve that is to zip both lists together and loop over that.
wb = load_workbook("Myworkbook.xlsx")
ws = wb.active
my_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
for rw in ws['E2:AH2']:
for cell, c in zip(rw, my_list):
cell.value = c
wb.save('Myworkbook.xlsx')
In your case for each cell the my_list is traversed to the end (by innermost for loop) having each cell assigned with last value, while it's needed to map cells and my_list values pairwise:
To fix that you can apply the following:
for row in ws['E2:AH2']:
for i, cell in enumerate(row):
cell.value = my_list[i]

Return the index of the first element in the list from where incremental increase starts

Suppose I have a list like this, where numbers increase in different steps:
[ 0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
I want to return the index for the first element in the list where the increase is incremental (+1 step only). In this case, 23 is the first location from which point the increase becomes incremental, and its index would be 8, which is what I want as an output.
What would be an elegant simple way to achieve this? This is what I have tried:
>>> for (a,b) in zip(l, l[1:]):
... if b-a == 1:
... print(l.index(a))
... break
UPDATE: In this particular setup, once the increase becomes incremental it will continue to stay that way. It is possible that the increase will never become incremental.
Solution 1: operator
from operator import sub, indexOf
L = [ 0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
print(indexOf(map(sub, L[1:], L), 1))
# prints 8
Raises ValueError: sequence.index(x): x not in sequence if difference 1 never occurs, so might want to use try/except for that.
Solution 2: bisect
This one only takes O(log n) time, using the monotonicity of incrementalness (as you commented "once the increase becomes incremental it will continue to stay that way").
from bisect import bisect
L = [ 0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
class IsIncremental:
def __getitem__(_, i):
return L[i+1] - L[i] == 1
print(bisect(IsIncremental(), False, 0, len(L) - 1))
# prints 8
Prints len(L) - 1 if difference 1 never occurs.
Btw... readability
As PEP 8 says:
Never use the characters 'l' (lowercase letter el), [...] as single character variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use 'l', use 'L' instead.
Steps:
Iterate over the array until the second last element.
Check if next element value differs from current element value by exactly 1.
Print the index and break the loop.
Code:
my_list = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
for i in range(len(my_list)-1):
if my_list[i+1] - my_list[i] == 1:
print(i)
break
Result:
8
Here is an iterative approach. We can loop over the list and take the following action at each index:
If the current value is one plus the previous, then don't move the incremental index
Otherwise, reset the incremental index to the current position
If we reach the end of the list and we have an incremental index which is earlier than the last position, then we have a potential match.
lst = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
idx = 0
for i in range(1, len(lst)):
if lst[i] != lst[i-1] + 1:
idx = i
if idx < len(lst) - 1:
print("Found index: " + str(idx) + ", value: " + str(lst[idx]))
else:
print("No incremental index found")
This prints:
Found index: 8, value: 23
Do a for each loop and check the previous value with the current. Once you reach a point where your current value is only 1 greater than the previous value, return the index of the previous value in your array:
myList = [ 0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
lastVal = -1000
for i in myList:
if i - lastVal == 1:
print(myList.index(lastVal)) #will print your desired value's index. If this is in a function, replace print with return
break
lastVal = i
if myList.index(lastVal) == len(myList) - 1:
print("There is no incremental increase in your array")
(edited, replaced return with lastVal, fixed to print the index)
Output:
8
Here is a way to do this using list comprehension
lst = [ 0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
list2 = [i-1 for i,j in enumerate(lst) if j-lst[i-1]==1]
if len(list2)>0:
print(list2[0])
else:
print('No one up number exists')
Similar to the previous answer.
myList = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
l0 = 0 #suppose that the initial value is 0
for l1 in myList:
increment = l1 - l0
if increment == 1:
print(myList.index(l0)) #if you want to get the second element, use l1 instead.
break #if you want to get all the first elements that has 1 increment, remove break
l0 = l1 #memorize l1

How to randomly select a specific sequence from a list?

I have a list of hours starting from (0 is midnight).
hour = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
I want to generate a sequence of 3 consecutive hours randomly. Example:
[3,6]
or
[15, 18]
or
[23,2]
and so on. random.sample does not achieve what I want!
import random
hourSequence = sorted(random.sample(range(1,24), 2))
Any suggestions?
Doesn't exactly sure what you want, but probably
import random
s = random.randint(0, 23)
r = [s, (s+3)%24]
r
Out[14]: [16, 19]
Note: None of the other answers take in to consideration the possible sequence [23,0,1]
Please notice the following using itertools from python lib:
from itertools import islice, cycle
from random import choice
hours = list(range(24)) # List w/ 24h
hours_cycle = cycle(hours) # Transform the list in to a cycle
select_init = islice(hours_cycle, choice(hours), None) # Select a iterator on a random position
# Get the next 3 values for the iterator
select_range = []
for i in range(3):
select_range.append(next(select_init))
print(select_range)
This will print sequences of three values on your hours list in a circular way, which will also include on your results for example the [23,0,1].
You can try this:
import random
hour = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
index = random.randint(0,len(hour)-2)
l = [hour[index],hour[index+3]]
print(l)
You can get a random number from the array you already created hour and take the element that is 3 places afterward:
import random
def random_sequence_endpoints(l, span):
i = random.choice(range(len(l)))
return [hour[i], hour[(i+span) % len(l)]]
hour = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
result = random_sequence_endpoints(hour, 3)
This will work not only for the above hours list example but for any other list contain any other elements.

extracting numbers from list

I've created a list (which is sorted):
indexlist = [0, 7, 8, 12, 19, 25, 26, 27, 29, 30, 31, 33]
I want to extract the numbers from this list that are at least five away from each other and input them into another list. This is kind of confusing. This is an example of how I want the output:
outlist = [0, 7, 19, 25, 31]
As you can see, none of the numbers are within 5 of each other.
I've tried this method:
for index2 in range(0, len(indexlist) - 1):
if indexlist[index2 + 1] > indexlist[index2] + 5:
outlist.append(indexlist[index2])
However, this gives me this output:
outlist = [0, 12, 19]
Sure, the numbers are at least 5 away, however, I'm missing some needed values.
Any ideas about how I can accomplish this task?
You need to keep track of the last item you added to the list, not just compare to the following value:
In [1]: indexlist = [0, 7, 8, 12, 19, 25, 26, 27, 29, 30, 31, 33]
In [2]: last = -1000 # starting value hopefully low enough :)
In [3]: resultlist = []
In [4]: for item in indexlist:
...: if item > last+5:
...: resultlist.append(item)
...: last = item
...:
In [5]: resultlist
Out[5]: [0, 7, 19, 25, 31]
This should do the trick. Here, as I said in comment, the outlist is initialised with the first value of indexlistand iterated indexlist elements are compared to it. It is a rough solution. But works.
indexlist = [0, 7, 8, 12, 19, 25, 26, 27, 29, 30, 31, 33]
outlist = [indexlist[0]]
for index2 in range(1, len(indexlist) - 1):
if indexlist[index2] > (outlist[-1] + 5):
outlist.append(indexlist[index2])
output:
>>outlist
[0, 7, 19, 25, 31]
Tim Pietzcker's answer is right but this can also be done without storing the last added item in a separate variable. Instead you can read the last value in outlist:
>>> indexlist = [0, 7, 8, 12, 19, 25, 26, 27, 29, 30, 31, 33]
>>> outlist = []
>>> for n in indexlist:
... if not outlist or n > outlist[-1] + 5:
... outlist.append(n)
...
>>> outlist
[0, 7, 19, 25, 31]
I suppose your index_list is sorted. Then this will give you only indexes MIN_INDEX_OFFSET apart.
MIN_INDEX_OFFSET = 5;
index_list = [0, 7, 8, 12, 19, 25, 26, 27, 29, 30, 31, 33];
last_accepted = index_list[0];
out_list = [last_accepted];
for index in index_list:
if index-last_accepted > MIN_INDEX_OFFSET:
out_list.append(index);
last_accepted = index;
print(out_list)

How to print an interval in sorted list

I want to know how to print numbers which are in sorted list. The interval will be given. For example:
list = [5, 10, 14, 18, 20, 30, 55]
and our interval input is between 11 and 29. So the program must print 14, 18,20.
You can simmply do as follows:
a_list = [5, 10, 14, 18, 20, 30, 55]
print([v for v in a_list if 11 <= v <= 29])
# Prints [14, 18, 20]
number_list = [5, 10, 14, 18, 20, 30, 55]
interval_list = [11,29]
result_list = []
for number in number_list:
if number in range(interval_list[0], interval_list[1]):
result_list.append(number)
print result_list

Categories