too many arguments for this formula - excel

I am making excel sheet but excel is not allowing me further checks and giving an error to many argument for this formula.
kindly give me solution.
=IF(E2="NL",N2-(J2*0.08),IF(AND(E2="PA",H2="Trip Travel"),(N2*0.01)+N2,(N2*0.02)+N2,IF(AND(E2="PK",H2="Trip Travel"),(J2*0.01)+N2,(J2*0.02)+N2)))
Edit to clarify possible scenarios:
1. E is "NL" and H is "Other" : return N2+(J2*0.08)
2. E is "NL" and H is "Trip Travel" : return N2+(J2*0.08)
3. E is "PK" and H is "Other" : return N2+(J2*0.01)
4. E is "PK" and H is "Trip Travel" : return N2+(J2*0.01)
5. E is "PA" and H is "Other" : return N2+(N2*0.02)
6. E is "PA" and H is "Trip Travel" : return N2+(N2*0.01)

The problem is the 2nd IF function, which has 4 arguments given. IF only takes 3:
The condition to test
The result if the condition is true
The result if the condition is false
The problematic section is:
IF(AND(E2="PA",H2="Trip Travel"), (N2*0.01)+N2, (N2*0.02)+N2, IF(AND(E2="PK",H2="Trip Travel"),(J2*0.01)+N2,(J2*0.02)+N2))
Notice how there are 4 arguments for the IF function in that section:
The condition: AND(E2="PA",H2="Trip Travel")
The result if true: (N2*0.01)+N2
The result if false: (N2*0.02)+N2
And then this extra argument: IF(AND(E2="PK",H2="Trip Travel"),(J2*0.01)+N2,(J2*0.02)+N2)
I'm not sure how exactly to correct this since I can't determine the logic you want from that formula. However, I'm guessing that either (N2*0.01)+N2 or (N2*0.02)+N2 belongs in a different section.
Also, just to help simplify the formula, the "+N2" could be put before the second IF and remove all the "+N2"s since all outcomes have N2 added to them. Something like the following (which still has the 4 arguments since I'm not sure how you want the logic corrected):
=IF(E2="NL",N2-(J2*0.08), N2+IF(AND(E2="PA",H2="Trip Travel"),(N2*0.01),(N2*0.02),IF(AND(E2="PK",H2="Trip Travel"),(J2*0.01),(J2*0.02))))
Edit the edited question:
This formula should cover the six possibilities in your spreadsheet:
=IFERROR(N2+IF(E2="NL",J2*0.08,IF(E2="PK",J2*0.01,IF(E2="PA",IF(H2="Trip Travel",N2*0.01,IF(H2="Other",N2*0.02,"n/a")),"n/a"))),"n/a")

Related

Python adding column with condition not working as expected

I am trying to add a column based on a condition like
for i in range(len(data) - 1):
a = data.loc[i, 'column1']
b = data.loc[i+1, 'column1']
if a == b:
data['column2'] = 1
else:
data['column2'] = 0
This shows no error and the new column has been created, however the logic does not work, the new column is filled with 0 regardless of the logic. I have checked if a == b by printing the values for a and b with a == b and the result is as I expected. I am not sure why that is?
Note that the reason why I am using if statements is because my logic involves if and, else if
Inside the if statement, it should be data.loc[i,'column2'] this way it will right in the value at that location

"buildSelect" function code in q/kdb generates error

The "buildSelect" function provided in this white paper generates error when I try to apply it to a select statement.
tidy:{ssr/[;("\"~~";"~~\"");("";"")] $[","=first x;1_x;x]};
strBrk:{y,(";" sv x),z};
//replace k representation with equivalent q keyword
kreplace:{[x] $[`=qval:.q?x;x;"~~",string[qval],"~~"]};
funcK:{$[0=t:type x;.z.s each x;t<100h;x;kreplace x]};
//replace eg ,`FD`ABC`DEF with "enlist`FD`ABC`DEF"
ereplace:{"~~enlist",(.Q.s1 first x),"~~"};
ereptest:{((0=type x) & (1=count x) & (11=type first x)) | ((11=type x)
&(1=count x))};
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]};
basic:{tidy .Q.s1 funcK funcEn x};
addbraks:{"(",x,")"};
//where clause needs to be a list of where clauses, so if only one where
clause need to enlist.
stringify:{$[(0=type x) & 1=count x;"enlist ";""],basic x};
//if a dictionary apply to both, keys and values
ab:{$[(0=count x) | -1=type x;.Q.s1 x;99=type x;(addbraks stringify key x
),"!",stringify value x;stringify x]};
inner:{[x]
idxs:2 3 4 5 6 inter ainds:til count x;
x:#[x;idxs;'[ab;eval]];
if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
//for select statements within select statements
x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];
x:#[x;ainds except idxs;string];
x[0],strBrk[1_x;"[";"]"]
};
buildSelect:{[x]
inner parse x
};
Got the following error message when applying buildSelect to a simple select statement:
ERROR: 'length
(incompatible lengths (different lengths of operands for synchronized operation or table columns lengths are not the same)
The issue seems to be with the select statement you are providing to the buildSelect function. I fyou remove the back tick the function now runs.
q)buildSelect"update idx:til count clock from `clock"
'length
[3] /home/lholmes/qsqltofunctional.q:23: inner:
if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];
^
x:#[x;ainds except idxs;string];
q))\
q)buildSelect"update idx:til count clock from clock"
"![clock;();0b;(enlist`idx)!enlist (til;(count;`clock))]"
This will produce the following:
q)t:([]time:10#.z.p)
q)update idx:i from t
time idx
---------------------------------
2019.06.19D08:39:15.720370000 0
2019.06.19D08:39:15.720370000 1
2019.06.19D08:39:15.720370000 2
2019.06.19D08:39:15.720370000 3
2019.06.19D08:39:15.720370000 4
2019.06.19D08:39:15.720370000 5
2019.06.19D08:39:15.720370000 6
2019.06.19D08:39:15.720370000 7
2019.06.19D08:39:15.720370000 8
2019.06.19D08:39:15.720370000 9
Hope this helps, if you have any additional questions feel free to ask.
For your clock table you dont even need command selectBuild. Q function parse will do the job. Simplify your code be leveraging virtual column i
parse "update idx:i from clock"
modified output:
![`clock; (); 0b; enlist[`idx]!enlist `i]
also, I recommend using
clock: update idx:i from clock
instead of
update idx:i from `clock
as the buildSelect does not handle the second form. Also, your code will run with a local clock table.
The reason why it doesn't work is that buildSelect is only expecting to be passed in tables by value in the parse tree, i.e., the element at the index 1 is expected to be an atomic symbol, not an enlist symbol, which is the case for parsing updates by name.
q)parse "update col1:val from tab"
!
`tab
()
0b
(,`col1)!,`val
q)parse "update col1:val from `tab"
!
,`tab
()
0b
(,`col1)!,`val
This causes issues at the following line in inner
x[1]:$[-11=type x 1;x 1;[idxs,:1;.z.s x 1]];
A more robust buildSelect can be made by the following adjustment
inner:{[x]
idxs:2 3 4 5 6 inter ainds:til count x;
x:#[x;idxs;'[ab;eval]];
if[6 in idxs;x[6]:ssr/[;("hopen";"hclose");("iasc";"idesc")] x[6]];
//for select statements within select statements
x[1]:$[-11=type x 1;x 1;$[11h=type x 1;[idxs,:1;"`",string first x 1];[idxs,:1;.z.s x 1]]];
x:#[x;ainds except idxs;string];
x[0],strBrk[1_x;"[";"]"]
};
Which will then allow for the following
q)buildSelect "update col1:val from `tab"
"![`tab;();0b;(enlist`col1)!enlist`val]"
q)buildSelect "update col1:val from tab"
"![tab;();0b;(enlist`col1)!enlist`val]"

Is this a right way to check pandigital number upto 9?

While solving problem 32 of project eular, I made this function to check pandigital number, is this a right way to check pandigital number? I think there is some problem, but I can't figure out it myself.
def pandigital(number, digit): # digit: n-digit pandigital number
l = ['{}'.format(j) for j in [i for i in range(1,digit+1)]]
g = list(str(number))
g.sort()
if g == l:
return True
Yes, there is a problem. In fact, three of them.
First, if a number contains more than one digit of the same denomination (duplicates), then g is not equal to l because l has only one copy of each digit. You should convert l and g to sets before the comparison.
Second, your function does not return anything if the number is not pandigital.
Finally, range(1,digit+1) does not include 0 (unless you want zeroless pandigital numbers).
Consider the following solution:
def pandigital(number, digit)
return {f'{i}' for i in range(digit)} == set(str(number))
Replace f'{i}' with '{}'.format(i) if you want to stick to more "classical" Python.

Using Comparative Operators to find local maxima in column of data frame

I have an excel file where each column represents successive time periods. I want to determine the local maxima for each time period (i.e., within each column). This is the code I have thus far:
import pandas as pd
df = pd.read_excel('my_sheet.xlsx', sheetname='Sheet1')
b = df['time_period_1']
i = 1
for i in b:
if b[i] > b[i-1] and b[i] > b[i+1]:
print(b[i])
i=i+1
Which gives the error
KeyError: 24223
24223 is the first value in the column
Any idea what is going on?
Thanks!
Beware that you are using "i" for both the increment inside of the loop and as an element of b. Basically "for i in b" puts the first value of "b" in "i", which is "24223" but this key is incorrect as certainly your column does not contain 24223 elements.
Basically, change the name of one of your index. For instance :
k = 1
for i in b:
if i > b[k-1] and i > b[k+1]:
print(b[k])
k += 1
(not sure here if you want to print(b[k]) or print(i), but you'll get the point)
Edit 1: you should use "i" as an object in "b", as you don't need it to be an index. When you use "for i in b", i is already the content of the cell. Use "b[i]" only when i is an index. So here, you either :
for i in range(len(b)) :
if b[i] > ...
where i is an index, or :
for i in b :
if i > ...
where i is an object.
Edit 2: to avoid accessing b[k+1] for the last index (which triggers an error as k+1 does not exist), use an if-condition. Also for clarity purposes, I would recommand using only one index. Note that to acheive this you also need a condition for the first row, as b[-1] would refer to the last row in python and I assume it is not what you want the first row to be compared to. Here is a code that should work:
for i in range(len(b)): #range begins implicitly at 0
if i > 0 and i < len(b)-1: #so you are not on the first nor last row
if b[i] > b[i-1] and b[i] > b[i+1]:
print(b[i])
elif i==0: #first row, to be compared with the following one only
if b[i] > b[i+1]:
print(b[i])
else: #last row, to be compared with the previous one only
if b[i] > b[i-1]:
print(b[i])
There would be mode concise and elegant ways to do so, but I think this one is the clearest.

What's x for x in input()?

I am new to coding and is trying to solve this python question
Question:
Write a program that calculates and prints the value according to the given formula:
Q = Square root of [(2 * C * D)/H]
Following are the fixed values of C and H:
C is 50. H is 30.
D is the variable whose values should be input to your program in a comma-separated sequence.
Example
Let us assume the following comma separated input sequence is given to the program:
100,150,180
The output of the program should be:
18,22,24
Hints:
If the output received is in decimal form, it should be rounded off to its nearest value (for example, if the output received is 26.0, it should be printed as 26)
In case of input data being supplied to the question, it should be assumed to be a console input.
This is the solution given. I have not seen 'x for x in input()'expression, may I know what does this expression do ?
import math
c=50
h=30
value = []
items=[x for x in input().split(',')]
for d in items:
value.append(str(int(round(math.sqrt(2*c*float(d)/h)))))
print (','.join(value))
This is my own solution but somehow I got a syntax error.
def sr(D):
For item in D:
return ((2*50*D)/30)**0.5
try:
a=int(input())
j=a.split(",")
print(sr(j))
except:
print('Please enter an integers or intergers seperated by comma')
The x is just a variable that gets assigned to the input that comes in via the input() function.
If you're aware of C style language (or Java), it's similar to
for(int i=0;<some_condition>;<some_operation>){}
This is just a condensed, pythonic and easy to read way to do this.
You can read more Python loops here
https://wiki.python.org/moin/ForLoop

Resources