Python If statement-differences - python-2.7

I try to learn the If statement forms integrated with For loop type, and i can't understand the differences between those codes because they give the same result:
grade = [100, 97, 73, 56, 78,34]
for i in range(0,len(grade)):
if grade[i]%2 == 0:
grade[i]= grade[i]+2
if grade[i]%3 ==0:
grade[i]= grade[i]+3
if grade[i]%5 ==0:
grade[i]= grade[i]+5
print grade
and this:
grade = [100, 97, 73, 56, 78,34]
for i in range(0,len(grade)):
if grade[i]%2 == 0:
grade[i]= grade[i]+2
if grade[i]%3 ==0:
grade[i]= grade[i]+3
if grade[i]%5 ==0:
grade[i]= grade[i]+5
print grade

When you have if statements one below another it's possible that something can match one OR another.
When you have nested if statements, to go through your condition has to match one AND another.
Consider in your first case: 10. It will pass %2 == 0 and %5 == 0, but not the %3 == 0. In second case it will only pass the first test and won't go to the nested ones.
For instance: 30 will pass all the if statements in both case.

Both code is same but the main difference is first code contains three if condition that executed top to bottom or one by one and second code contains three nested if condition statement that execute if first statement is true
learn more from c-sharpcorner.com

Related

python recursion is not working as expected

I'm new to coding and trying to teach myself about recursion by building a very simple function that calls itself. However my code is behaving slightly differently to how I was expecting:
get user input number that must not be greater than 50
def getinput():
input = int(raw_input("type number under 50 >>> "))
if input < 50:
return input
else:
print input, "no, must be under 50"
getinput()
print getinput()
This results in the following behavior:
This bit as expected
C:\Python27>python recur.py
type number under 50 >>> 23
23
This bit unexpected
C:\Python27>python recur.py
type number under 50 >>> 63
63 no, must be under 50
type number under 50 >>> 23
None
My question is, why is the last line "None", and not 23? My code seems to correctly call the function again if the user inputs a number 50 or greater, but why doesn't the second call return 23 (the same as the initial output)?
Any advice much appreciated
You don't return the result of the getInput() if the number is greater than 50
def getinput():
input = int(raw_input("type number under 50 >>> "))
if input < 50:
return input
else:
print input, "no, must be under 50"
return getinput()
print getinput()
You missed a return in the else condition. The following code should work:
def getinput():
input = int(raw_input("type number under 50 >>> "))
if input < 50:
return input
else:
print input, "no, must be under 50"
return getinput()
print getinput()
In this case your function will return input
if input < 50:
return input
You are using recursion, so it is just like a stack at the end all the return values will come back to the function which was called. When the condition if input < 50 not satisfied it will return None and you are using print(getinput()).
| 23 |
| 63 | -> None
-----
That's just my understanding about recursion.
so when the value is greater than 50, do return a value instead of None to the function back.
return getinput()
Also please use different variable names instead of input.

Separating columns from a file by last column

I'm trying to do this: if the last column is negative number from 1-5 then write second and last column to a file "neg.txt". If a last column is positive number, second and last column need to be written to "pos.txt". My both output files end up empty after execution. I don't know what's wrong with the code, when I think if statement can handle multiple conditions. I also tried with regular expressions but it did't work so I made it as simple as possible to see what is not working.
The input file looks like this:
abandon odustati -2
abandons napusta -2
abandoned napusten -2
absentee odsutne -1
absentees odsutni -1
aboard na brodu 1
abducted otet -2
accepted prihvaceno 1
My code is:
from urllib.request import urlopen
import re
pos=open('lek_pos.txt','w')
neg=open('lek_neg.txt','w')
allCondsAreOK1 = ( parts[2]=='1' and parts[2]=='2' and
parts[2]=='3' and parts[2]=='4' and parts[2]=='5' )
allCondsAreOK2 = ( parts[2]=='-1' and parts[2]=='-2' and
parts[2]=='-3' and parts[2]=='-4' and parts[2]=='-5' )
with open('leksicki_resursi.txt') as pos:
for line in pos:
parts=line.split() # split line into parts
if len(parts) > 1: # if at least 2 columns (parts)
if allCondsAreOK:
pos.write(parts[1]+parts[2])
elif allCondsAreOK2:
neg.write(parts[1]+parts[2])
else:
print("nothing matches")
You don't need a regex, you just need an if/elif checking if after casting to int the last value falls between -5 and -1, if it does you write to the neg file or if the value is any non negative number you write to the pos file:
with open('leksicki_resursi.txt') as f, open('lek_pos.txt','w')as pos, open('lek_neg.txt','w') as neg:
for row in map(str.split, f):
a, b = row[1], int(row[-1])
if b >= 0:
pos.write("{},{}\n".format(a, b))
elif -5 <= b <= -1:
neg.write("{},{}\n".format(a, b))
If the positive nums must also be between 1-5 then you can do something similar to the negative condition:
if 5 >= int(b) >= 0:
pos.write("{},{}\n".format(a, b))
elif -5 <= int(b) <= -1:
neg.write("{},{}\n".format(a, b))
Also if you have empty lines you can filter them out:
for row in filter(None,map(str.split, f)):

Can I add an else to a simplified if statement?

I'll be honest, I could not think of what to address this problem as.
I was looking on Coffeescript.org to see if there was a nicer way to handle multiple OR's in an if statement
They showed an example of displaying this:
if (pick === 47 || pick === 92 || pick === 13) {
winner = true;
}
List this this:
winner = yes if pick in [47, 92, 13]
My problem is that I can seem to put an else at the end of the if statement when I have it formatted the new way. Are you even allowed to?
Thanks for your time!
You have to use if...then if you want to use an else:
winner = if pick in [47, 92, 13] then yes else no
However, you can still do multi-line ifs:
if pick in [47, 92, 13]
winner = true
else
winner = false
Also, note that the in operator returns a boolean, so you can assign that directly.
winner = pick in [47, 92, 13]
is equivalent to my first example.

How to switch directly to the desired condition without checking other conditions in Python?

I have an python example code as:
Input: (x,y)
if x==0 and y==0:
print x+y+1
elif x==0 and y==y:
print x+y*y+2
elif x==x and y==0:
print x*x+y+3
else:
print x*x+y*y+4
How can I switch directly to the condition as, if my input is (x,y) = (0,0) it will output 1 without checking other conditions?
I tried this using dictionary as,
Input: (x,y)
def Case1():
print x+y+1
def Case2():
print x+y*y+2
def Case3():
print x*x+y+3
def Case4():
print x*x+y*y+4
dict = {(0,0): Case1,
(0,y): Case2,
(x,0): Case3,
(x,y): Case4,
}
dict[(x,y)]()
When I tried this with input (x,y) = (0,0), this gives me output as 4 instead of 1. It seems like, my code is checking only for the Case4. What I am doing wrong in the dictionary?
Thanks!
It seems that you do not quite understand how Python works. A dictionary is not a pattern matching block, as you have in Haskell or Erlang. It is a data structure with concrete values inside. You can try to write print dict after your definition and see what's inside it.
When you create your dict, current concrete values of x and y are used to create the keys. If x and y happen to be 0 at the time, the (0,0) key will be replaced by (x,y) (that's why in your case Case4 is called).
Bogdan explained why you can not use the variables x and y as keys into your dictionary. When they are both zero, all 4 keys will be (0,0) at definition time, so the dictionary only contains one case. You can probably achieve what you want by using the result of the tests on x and y as a key into the dictionary instead (untested):
case_dict = {(True, True): Case1,
(True, False): Case2,
(False, True): Case3,
(False, False): Case4,
}
case_dict[(x == 0, y == 0)]()
Note that you should not call a variable dict, since this is the name of a built-in type.
Say x=0 and y=0. Your final entry in the dict is (x,y):Case4, or 0,0, replacing any previous 0,0. Then you look up dict[x,y], or really dict[0,0] which calls Case4...this will happen regardless of what x,y is.
Stick to your original if. The code is clear, although you can make it simpler:
if x==0 and y==0:
print 1
elif x==0:
print y*y+2
elif y==0:
print x*x+3
else:
print x*x+y*y+4

JasperReports: Converting String into array and populating List with it

What I have is this String [125, 154, 749, 215, 785, 1556, 3214, 7985]
(string can have anything from 1 to 15 ID's in it and the reason it is a string and not a List is that, its being sent through a URL)
I need to populate a List called campusAndFaculty with it
I am using iReport 5.0.0
I've tried entering this in the campusAndFaculty default value Expression field
Array.asList(($P{campusAndFacultyString}.substring( 1, ($P{campusAndFacultyString}.length() -2 ))).split("\\s*,\\s*"))
But it does not populate the campusAndFaculty List
Any idea how I can populate the List campusAndFaculty using that String ("campusAndFacultyString")?
======================
UPDATE
I have these variables in iReport (5.0.0)
String campusAndFacultyFromBack = "[111, 125, 126, 4587, 1235, 1259]"
String noBrackets = $P{campusAndFacultyFromBack}.substring(1 ($P{campusAndFacultyFromBack}.length() -1 ))
List campusAndFacultyVar = java.util.Arrays.asList(($V{noBrackets}).split("\\s*,\\s*"))
When I print campusAndFacultyVar It returns "[111, 125, 126, 4587, 1235, 1259]"
but when I use it in a Filter I get the "Cannot evaluate the following expression: org_organisation.org_be_id in null"
This works for me:
String something = "[125, 154, 749, 215, 785, 1556, 3214, 7985]";
Arrays.asList((something.substring(1, (something.length() -1 ))).split("\\s*,\\s*"));
Which means you can do this in iReport:
java.util.Arrays.asList(($P{campusAndFacultyString}.substring(1, (something.length() -1 ))).split("\\s*,\\s*"));
Differences with your snippet:
It's Arrays, not Array
You should take 1, not 2 from the length
Fully qualified reference to Arrays class (which may or may not matter depending on how your iReport is configured)