python's lists ,tuples and for loop - python

i have a list :
a=[1, 2, 3, 300] # this is IDs of workers
And a list of tuples :
f=[(1, 1, 1), (1, 0, 0), (0, 0, 0), (1, 500, 600)]
For every element in a ( a[i]) it has a related element (tuple) in f ( f[i) ) . So what i need is to sum the elements in f[i] for every a[i] till certain indices according to user . For example if user want the summation to end till certain index say 2 , the output will then be for ID 1=a[0] --> sum will be 2 (f[0]=1 +f[1]=1 ) , for ID 2=a[2] --> the summation is 1 [f[0]=0+f[1]=1] and so on till a[3]
here is my code :
str1=int(input('enter the index[enter -->1/2/3]'))
a=[1, 2, 3, 300]
f=[(1, 1, 1), (1, 0, 0), (0, 0, 0), (1, 500, 600)]
length=len(a)
temp=0 #sum
for i in range(0,length):
y=a[i]
att_2=f[i]
print("{} {}".format("The worker ID is ", y))
for z in range(0,(str1)):
temp=temp+att_2[i]
print(temp) # tracing the sum
I getting a error plus wrong result for some a[i] :
enter the index[enter -->1/2/3]2
temp=temp+att_2[i]
IndexError: tuple index out of range
The Student ID is 1
1
2
The Student ID is 2
2
2
The Student ID is 3
2
2
The Student ID is 300
Process finished with exit code 1
I am trying to fix these errors , but i cannot find its reasons. Thank you

Your Error is because you have mixed up the variable i and the variable z.
Your code loops through the tuple using variable i and that will result in an error as the maximum value i will take is calculated for another set of instructions.
A switch of variables on line 11 will fix your problems
Original:
str1=int(input('enter the index[enter -->1/2/3]'))
a=[1, 2, 3, 300]
f=[(1, 1, 1), (1, 0, 0), (0, 0, 0), (1, 500, 600)]
length=len(a)
temp=0 #sum
for i in range(0,length):
y=a[i]
att_2=f[i]
print("{} {}".format("The worker ID is ", y))
for z in range(0,(str1)):
temp=temp+att_2[i]
print(temp) # tracing the sum
New:
str1=int(input('enter the index[enter -->1/2/3]'))
a=[1, 2, 3, 300]
f=[(1, 1, 1), (1, 0, 0), (0, 0, 0), (1, 500, 600)]
length=len(a)
temp=0 #sum
for i in range(0,length):
y=a[i]
att_2=f[i]
print("{} {}".format("The worker ID is ", y))
for z in range(0,(str1)):
temp=temp+att_2[z]
print(temp) # tracing the sum

Related

Getting all possible combination for [1,0] with length 3 [0,0,0] to [1,1,1]

from itertools import combinations
def n_length_combo(arr, n):
# using set to deal
# with duplicates
return list(combinations(arr, n))
# Driver Function
if __name__ == "__main__":
arr = '01'
n = 3
print (n_length_combo([x for x in arr], n) )
Expected Output
wanted 3 combination of 0 and 1 .Tried with above example but it is not working
You're looking for a Cartesian product, not a combination or permutation of [0, 1]. For that, you can use itertools.product.
from itertools import product
items = [0, 1]
for item in product(items, repeat=3):
print(item)
This produces the output you're looking for (albeit in a slightly different order):
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)

How to random assign 0 or 1 for x rows depend upon y column value in excel

I'm trying to generate a below sample data in excel. There are 3 columns and I want output similar present to IsShade column. I've tried =RANDARRAY(20,1,0,1,TRUE) but not working exactly.
I want to display random '1' value only upto value present in shading for NoOfcells value rows.
NoOfCells Shading IsShade(o/p)
5 2 0
5 2 0
5 2 1
5 2 0
5 2 1
--------------------
4 3 1
4 3 1
4 3 0
4 3 1
--------------------
4 1 0
4 1 0
4 1 0
4 1 1
Appreciate if anyone can help me out.Python code will also work since the excel I will read in csv and try to generate output IsShade column. Thank you!!
A small snippet of Python that writes your excel file. This code does not use Pandas or NumPy, only the standard library, to keep it simple if you want to use Python with Excel.
import random
import itertools
import csv
cols = ['NoOfCells', 'Shading', 'IsShade(o/p)']
data = [(5, 2), (4, 3), (4, 1)] # (c, s)
lst = []
for c, s in data: # c=5, s=2
l = [0]*(c-s) + [1]*s # 3x[0], 2x[1] -> [0, 0, 0, 1, 1]
random.shuffle(l) # shuffle -> [1, 0, 0, 0, 1]
lst.append(zip([c]*c, [s]*c, l))
# flat the list
lst = list(itertools.chain(*lst))
with open('shade.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile, delimiter=',')
writer.writerow(cols)
writer.writerows(lst)
>>> lst
[(5, 2, 1),
(5, 2, 0),
(5, 2, 0),
(5, 2, 0),
(5, 2, 1),
(4, 3, 1),
(4, 3, 0),
(4, 3, 1),
(4, 3, 1),
(4, 1, 0),
(4, 1, 0),
(4, 1, 1),
(4, 1, 0)]
$ cat shade.csv
NoOfCells,Shading,IsShade(o/p)
5,2,0
5,2,0
5,2,1
5,2,0
5,2,1
4,3,1
4,3,1
4,3,1
4,3,0
4,1,0
4,1,1
4,1,0
4,1,0
You can count the number or rows for RANDARRAY to return using COUNTA. Also. to exclude the dividing lines, test for ISNUMBER
=LET(Data,FILTER(B:B,(B:B<>"")*(ROW(B:B)>1)),IF(ISNUMBER(Data),RANDARRAY(COUNTA(Data),1,0,1,TRUE),""))

How to maximise addition/subtraction combinations?

Suppose I have a list of 10 elements [a, b, c, d, e, f, g, h, i, j] and I can multiply each element by 0, 1, 2, -1, -2.
The total of the multiplication factors I use must be equal to zero. Ie if I multiply five numbers by -1 I must multiply the other five by 1, or I can multiply a by 2, b and c by -1 and the rest by 0.
I want to find the list resulting from this operation that has the largest sum.
How can I go about coding this in python?
I've tried coding every single iteration of [2, 1, 0, -1, -2] and deleting the lists that do not add to 0 and then multiplying by the original list, however I got stuck.
You can sort the list, scan it from the ends towards the center, assigning 2 to the larger element and -2 to the smaller.
def baby_knapsack(xs):
xs = sorted(xs, reverse=True)
res = list()
n = len(xs)
for i in range(n//2):
res.extend(((xs[i], 2), (xs[-1-i], -2)))
if n % 2 == 1:
res.append((xs[n//2], 0))
return res
xs = [-10, -5, 0, 5, 10, 15]
# In [73]: q.baby_knapsack(q.xs)
# Out[73]: [(15, 2), (-10, -2), (10, 2), (-5, -2), (5, 2), (0, -2)]

'int' object is not iterable" when use itertools and apply function to each row

I have the following dataset:
index REWARD
(1,1,1) 0
(1,2,3) 0
(1,1,3) 0
I want to set REWARD = 2 if index have a pair of numbers. So output should look like
index REWARD
(1,1,1) 0
(1,2,3) 0
(1,1,3) 2
when I use this code
def set_reward(final):
for i in final['index']:
tempCount=[]
for item,count in collections.Counter((i)).items():
tempCount.append(count)
if tempCount==[2, 1] or tempCount==[1, 2]:
final['REWARD']=2
return final['REWARD']
final['REWARD']=final.apply(set_reward,axis=1)
It says that 'int' object is not iterable"
Are there any ways to resolve it?
You can achieve the desired result without explicit for looping and conditional logic. Try something like this:
# Example data
df = pd.DataFrame({'index': [(1, 1, 1), (1, 2, 3), (1, 1, 3)],
'REWARD': [0, 0, 2]})
# Select any row whose index contains at least one pair of values
mask = df['index'].apply(lambda x: 2 in Counter(x).values())
df.loc[mask, 'REWARD'] = 2
df
index REWARD
0 (1, 1, 1) 0
1 (1, 2, 3) 0
2 (1, 1, 3) 2

How to count how many times a value repeats a minimum number of times [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a DataFrame with two columns. The first being time which is just counting up from 1.
The important one is a bunch of 1's and 0's. I want to know how many times 1 repeats a specific n times. For instance, let's say I have 100 values of randomly placed 1's and 0's, I want to know how many times I have at least five 1's in a row. Meaning that I'd like to know the number of times it repeats 5, 6, 7, or anything greater number of times.
Has anyone done anything similar to this before?
Try:
np.random.seed(1234)
df=pd.DataFrame(np.random.choice([0,1], 100))
(df.groupby(df[0].ne(1).cumsum().where(df[0] == 1)).count() > 4).sum().values[0]
Output:
2
Do you want to know besides how many, how long each repetition chain is and even where it is?
Consider the following function:
def consec_ones_cntr(it, thrshld):
n = 0
for i, v in enumerate(it):
if v:
n += 1
else:
if n >= thrshld:
yield i-n, n
n = 0
I feel free to use #ScottBostons sample data:
# import numpy as np
# import pandas as pd
# np.random.seed(1234)
# df=pd.DataFrame(np.random.choice([0,1], 100))
Then the usage of the function would be:
print(list(consec_ones_cntr(df[0], 5)))
which results in
# [(7, 5), (70, 7)]
meaning that there are 5 ones between index 7 and 11, and another 7 ones between 70 and 76.
Less elegant way to do it.
df['diff'] = df['Column'].diff()
df = df.fillna(0)
repeats = 0
y = 0
for x in df.itertuples():
if x.diff == 0:
y+=1
else:
if y >= 5:
repeats += 1
y = 0
I am using itertools.groupby, with np.unique
import itertools
x,y=np.unique([tuple(y) for x , y in itertools.groupby(df[0])],return_counts =True)
x
Out[343]:
array([(0,), (0, 0), (0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0), (1,), (1, 1), (1, 1, 1), (1, 1, 1, 1),
(1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1)], dtype=object)
y
Out[344]: array([13, 6, 3, 1, 1, 14, 5, 3, 1, 1, 1], dtype=int64)
For better display
df= pd.DataFrame(x.tolist()).assign(Number=lambda x : x.count(1),Unique=y).dropna(1)
df
Out[350]:
0 Number Unique
0 0 1 13
1 0 2 6
2 0 3 3
3 0 8 1
4 0 9 1
5 1 1 14
6 1 2 5
7 1 3 3
8 1 4 1
9 1 5 1
10 1 7 1

Categories

Resources