Finding Inequality of 4 variables using Nested If else only - python

Lets say I have 4 variables, a,b,c and d.
I'm trying to write a code(in the shortest formate) using only If Else (in nested formate) to arrange the variables in accensending order.
I'm sure their possibly are ways to do it smothly but using this method do you think if the code can be shortened
Do you guys have any simpler way of finding inequality in such a way
**```
a=19
b=10
c=1
d=8
if a>b:
print()
if a>c:
print() #ALL OK
if a>d:
print()
if b>c:
print()
if c>d:
print("a>b>c>d")
else:
print("a>b>d>c")
else:
print()
if b>d:
print("a>c>b>d")
else:
print("a>c>d>b")
else:
print()
if b>c:
print("d>a>b>c")
else:
print("d>a>c>b")
else:
print()
if a>d:
print()
if d>b:
print("c>a>d>b")
else:
print("c>a>b>d")
else:
print()
if c>d:
print("c>d>a>b")
else:
print("d>c>a>b")
else:
print()
if b>c:
print()
if b>d:
print()
if a>c:
print()
if c>d:
print("b>a>c>d")
else:
print("b>a>d>c")
else:
print()
if a>d:
print("b>c>a>d")
else:
print("b>c>d>a")
else:
print()
if c>a:
print("d>b>c>a")
else:
print("d>b>a>c")
else:
print
if c>d:
print()
if a>d:
print("c>b>a>d")
else:
print("c>b>d>a")
else:
print("d>c>b>a")
```
`
```**

Probably don't want to use nested statements in this scope, as you can see it get's unweildly very quickly.
a = 19
b = 10
c = 1
d = 8
# Note you can shorten the nesting by using multi-conditional (might not be the term!)
if a > b > c > d: print("a>b>c>d")
elif b > c > d > a: print("b>c>d>a") # and so on..
# but you're still looking at hardcoding every possible permutation of [a, b, c,d] or in the event of a dataset with X elements..
# Nested if's are useful but not in this scope
# In the context of this problem it would be better to sort
# the data and create a string based on that
as_dict = {"a": a, "b": b, "c": c, "d": d}
sorted_d = sorted(as_dict, key=lambda x: as_dict[x])[::-1]
print(">".join(sorted_d))

#Pure pythonic You can try uisng and which will be clean & Append results to str order accordingly
a=19
b=10
c=1
d=8
s=''
how_many_var =4
for i in range(how_many_var):
if a > b and a > c and a > d:
print(a)
a=0
s += 'a>'
elif b > a and b > c and b > d:
print(b)
b=0
s += 'b>'
elif c > a and c > b and c > d:
print(c)
c=0
s += 'c>'
elif d > a and d > b and d > c:
print(d)
d=0
s += 'd'
print(s)
output #
19
10
8
1
a>b>d>c

Related

Python Falls Into If but Return Not Working

I'm just trying to do a simple hackerrrank question. The code I've come up with prints out the answer but doesn't return it. I'm not sure why.
def myjump(c,j):
if len(c) <= 1:
print("answer: ",j)
return j
elif len(c) > 2:
if c[2] == 0:
c = c[2:]
else:
c = c[1:]
else:
c = c[1:]
j += 1
myjump(c,j)
return "Test"
def jumpingOnClouds(c):
if len(c) <= 1:
return 0
res = myjump(c,0)
print("return: ",res)
return res
result = jumpingOnClouds([0,0,1,0,0,1,0])
The output:
('answer: ', 4)
('return: ', 'Test')
I don't understand why the code seems to fall into the "if len(c) <= 1:" block and print the number but doesn't hit that return?
You have a recursive function; the recursive call doesn't return myjump(c, j) so you're breaking the chain (if this was supposed to be recursive at all - maybe the function calling itself is a mistake?)

Nested if ... else (Python exercise)

I'm trying to build a function that checks which of a,b,c is less then returns the lesser value.
def minimal_three(a,b,c):
if a < b:
if a < c:
return (a)
elif b < a:
if b < c:
return (b)
elif c < a:
if c < b:
return (c)
else:
return 'none'
So far the code runs fine until it gets to check 'c', then it doesnt return anything, nested if else statements already get really confusing to me.
You shouldn't use if-else as the 3 conditions are not exclusive.
For example, [3, 4, 1] should return in the 3rd condition but is also suitable in the 1st condition, so it returns nothing.
If you don't want to change your code a lot. You can use:
def minimal_three(a,b,c):
if a < b:
if a < c:
return (a)
if b < a:
if b < c:
return (b)
if c < a:
if c < b:
return (c)
return 'none'
For simple, you can try:
def minimal_three(a,b,c):
return min(a, b, c)
why that code doesn't work:
def minimal_three(a,b,c):
if a < b:
if a < c:
return (a)
else:
# what if a >= c and a < b ?
return "i returned nothing"
elif b < a:
if b < c:
return (b)
else:
# what if b >= c and a > b ?
return "i returned nothing"
elif c < a:
if c < b:
return (c)
else:
# what if b <= c and a < c ?
return "i returned nothing"
else:
return 'none'
Alternative:
def min_of_two(a, b):
if a > b:
return b
return a
def min_of_three(a, b, c):
min_ab = min_of_two(a, b)
min_abc = min_of_two(min_ab, c)
return min_abc
def min_of_three_v2(a, b, c):
min_ab = a
if a > b:
min_ab = b
min_abc = min_ab
if min_ab > c:
min_abc = c
return min_abc
def min_of_three_v3(a, b, c):
min_abc = a
if min_abc > b:
min_abc = b
if min_abc > c:
min_abc = c
return min_abc
if you really want to use nested if/else (this code is so long):
# if-elif-else is ok.
# nested if is hard to read
# if-elif-elif-elif-elif...-else is hard to read.
# hard to read == easy to have bugs, which is bad.
def min_abc_slower(a, b, c):
if a > b:
# a > b. This means min(a, b) == b
if b > c:
# b > c. This means min(c, min(a, b)) == c
return c
else:
# b > c is False. This means b <= c.
# So, min(c, min(a, b)) == b
return b
else:
# a > b is False. This means a <= b.
# So, min(a, b) = a
if a > c:
# a > c. This means min(c, min(a, b)) == c
return c
else:
# a > c is False. This means a <= c
# So, min(c, min(a, b)) == a
return a
Use the power of if...elif...else over if...if...if or if...else...if...else. The way you have written your code, depreciates the power of elif. The correct way should be as this:
def minimal_three(a,b,c):
if a < b and a < c:
return (a)
elif b < c:
return (b)
else
return (c)
This code will always return the min no matter what numbers you give.
Explaination:
In your code, the line if a < b already tells you the comparison between a and b that which one is greater. So checking for this condition again in the second if if b < a is useless. if a is not lesser than b, then obviously it is either greater than b or equal to b. So now you must just check if b is lesser than c to prove that b is smallest or even a or b both but the returned value is always minimum. I hope you get that.
Also I don't understand whyt do you want to return None. If you provide three numbers to a function to find the minimum number, it should always and always return a number. Tell me a case where you can expect a None.
Easily be done using min inbuilt function:
def min_value(a,b,c):
return (min(a,min(b,c)))
also the number of steps in your code can be reduced with some tweaking.
It works - Finding two greatest in three int:
def Biggest(a, b, c):
if a >= b >= c:
print a, b, 'are the biggest two'
elif b >= c >= a:
print b, c, 'are the biggest two'
else:
print c, a, 'are the biggest two'
Find greatest in three integer:
def Biggest(a, y, z):
Max = a
if y > Max:
Max = y
if z > Max:
Max = z
if y > z:
Max = y
return Max
You could probably get away with using a for loop to minimise lines of code!
It would look something like this:
c = 3
b = 2
a = 1
list = [a,b,c]
def minimal_three(a,b,c):
for y in list:
n = y
for x in list:
if x < n:
print(n)

How to break out a function without return or break in Python

I'm dfs traversing between nodes a and b, however when I break the loop at node b the algorithm continues. Here is my code:
import networkx as nx
def Graph():
G=nx.Graph()
k = 30
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(1,3)
for i in range(2,k+1):
G.add_edge(2*i-2,2*i)
G.add_edge(2*i-1,2*i)
G.add_edge(2*i-1,2*i+1)
G.add_edge(2*i,2*i+1)
G.add_nodes_from(G.nodes(), color='never coloured')
G.add_nodes_from(G.nodes(), label = -1)
G.add_nodes_from(G.nodes(), visited = 'no')
return G
def dfs(G,a,b,u):
global i
G.node[u]['visited'] = 'yes'
i += 1
G.node[u]['label'] = i
print(u)
print("i", i)
for v in G.neighbors(u):
if v == b:
G.node[v]['visited'] = 'yes'
i += 1
G.node[v]['label'] = i
print("b is ", v)
print("distance from a to b is ", G.node[v]['label'])
break### the problem area, doesn't break out the function
elif v != b:
if G.node[v]['visited'] == 'no':
dfs(G,a,b,v)
G=Graph()
a=1
b=19
i = 0
print('Depth-First-Search visited the following nodes of G in this order:')
dfs(G,a,b,a) ### count the DFS-path from a to b, starting at a
print('Depth-First Search found in G7 a path between vertices', a, 'and', b, 'of length:', G7.node[b]['label'])
print()
I have tried returning out of the for loop, tried using break and also tried try/catch methods. Is there any elegant way to break out this function or will I have to rewrite it as it doesn't recurse through all neighbors of u?
The problem here is not break or return, but that you use recursion and you don't stop the loop in each recursive call. What you need to do is to return a result from your dfs function that tells whether you found your node or not, and then break the loop inside your else block if the recursive call did find it. Something like this:
def dfs(G,a,b,u):
global i
G.node[u]['visited'] = 'yes'
i += 1
G.node[u]['label'] = i
print(u)
print("i", i)
for v in G.neighbors(u):
if v == b:
G.node[v]['visited'] = 'yes'
i += 1
G.node[v]['label'] = i
print("b is ", v)
print("distance from a to b is ", G.node[v]['label'])
return True
elif v != b:
if G.node[v]['visited'] == 'no':
found = dfs(G,a,b,v)
if found:
return True
return False
Note how this propagates the successful result back up through your entire call stack.
In such cases I often use global flag variable to indicate that the searching is finished. For example path_found.
If I understand well, your problem is not that you can't exit the function.
The problem is that you are not breaking out from recursion. There are many ways of fixing this.
This is one of many examples. By returning True and checking that in every call, you start bubbling up and skipping at every loop along your recursion. You can understand the True value as 'path found'
def dfs(G,a,b,u):
global i
G.node[u]['visited'] = 'yes'
i += 1
G.node[u]['label'] = i
print(u)
print("i", i)
for v in G.neighbors(u):
if v == b:
G.node[v]['visited'] = 'yes'
i += 1
G.node[v]['label'] = i
print("b is ", v)
print("distance from a to b is ", G.node[v]['label'])
return True
elif v != b:
if G.node[v]['visited'] == 'no':
if dfs(G,a,b,v):
return True

Python sum of non duplicate int

I am given 3 int, a, b, c. I would like to find the sum of all three int provided that they are unique. If a, b, or c has the same values as any of the other values, then they don't count towards the sum.
Example 1:
a = 3, b = 3, c =3
sum = 0
Example 2
a = 1, b = 3, c =3
sum = 1
This is what I have done. Is there a more pythonic way of doing this without so many if else statements?
def lone_sum(a, b, c):
if a != b and b != c and a != c:
return a + b + c
elif a == b == c:
return 0
elif a == b:
return c
elif b == c:
return a
elif a == c:
return b
from collections import Counter
def lone_sum(a, b, c):
d = Counter([a, b, c])
return sum(k for k in d if d[k]==1)
Add any number of numbers:
def lone_sum(*L):
d = Counter(L)
return sum(k for k in d if d[k]==1)
Add numbers repeated exactly c times:
def rep_sum(c, *L):
d = Counter(L)
return sum(k for k in d if d[k]==c)
Add numbers repeated at most c times:
def rep_sum(c, *L):
d = Counter(L)
return sum(k for k in d if d[k]<=c)
... or if you're bored and want to get really creative:
def lone_sum(*L):
nums = set()
all_nums = set()
for num in L:
if num in nums:
nums.remove(num)
elif num not in all_nums:
all_nums.add(num)
nums.add(num)
return sum(nums)
Here is a good beginners way to solve it
def lone_sum(*args):
return sum(x for x in args if args.count(x) == 1)
The issue with this is that args.count is a hidden loop, so the calculation becomes O(n2)
This doesn't matter much if there are only ever 3 arguments - ie n == 3.
A longhand way to write the same thing is
def lone_sum(a, b, c):
args = (a, b, c)
s = 0
for x in args:
if args.count(x) == 1:
s += x
return s
Here I take a list of your numbers, call it x, and then select only those x[i] which are not present in a list which is x without x[i]. That is, it removes all numbers which have a duplicate.
def lone_sum(a, b, c):
x = [a,b,c]
x = [x[i] for i in range(len(x)) if x[i] not in [x[j] for j in range(len(x)) if j!=i]]
return sum(x)
So,
[x[j] for j in range(len(x)) if j!=i]
is basically a list of elements excluding x[i]. It takes all elements apart from ith. If x[i] is in this list, it means it is a duplicate and we need to remove it. That is,
x[i] not in [x[j] for j in range(len(x)) if j!=i]
I think a lot has already been said and done on this topic and there is not much that can be added. But I too have written a program that uses sets to go about this task which is a little different from the top answer. So if you still wish to see all possible programs then here you go. Hope it helps!
def lone_sum(x):
c = set(x)
for b in c:
x.remove(b)
for a in set(x):
if a in c:
c.remove(a)
return(sum(c))

Looking for a more pythonic logical solution

I was doing some practice problems in Coding Bat, and came across this one..
Given 3 int values, a b c, return their sum. However, if one of the values is the same as another of the values, it does not count towards the sum.
lone_sum(1, 2, 3) → 6
lone_sum(3, 2, 3) → 2
lone_sum(3, 3, 3) → 0
My solution was the following.
def lone_sum(a, b, c):
sum = a+b+c
if a == b:
if a == c:
sum -= 3 * a
else:
sum -= 2 * a
elif b == c:
sum -= 2 * b
elif a == c:
sum -= 2 * a
return sum
Is there a more pythonic way of doing this?
Another possibility that works for an arbitrary number of arguments:
from collections import Counter
def lone_sum(*args):
return sum(x for x, c in Counter(args).items() if c == 1)
Note that in Python 2, you should use iteritems to avoid building a temporary list.
How about:
def lone_sum(*args):
return sum(v for v in args if args.count(v) == 1)
A more general solution for any number of arguments is
def lone_sum(*args):
seen = set()
summands = set()
for x in args:
if x not in seen:
summands.add(x)
seen.add(x)
else:
summands.discard(x)
return sum(summands)
Could use a defaultdict to screen out any elements appearing more than once.
from collections import defaultdict
def lone_sum(*args):
d = defaultdict(int)
for x in args:
d[x] += 1
return sum( val for val, apps in d.iteritems() if apps == 1 )
def lone_sum(a, b, c):
z = (a,b,c)
x = []
for item in z:
if z.count(item)==1:
x.append(item)
return sum(x)
Had a very similar approach to what you had:
def lone_sum(a, b, c):
if a != b and b != c and c != a:
return a + b + c
elif a == b == c:
return 0
elif a == b:
return c
elif b == c:
return a
elif c == a:
return b
Since if 2 values are the same the code will automatically return the
remaining value.
I tried this on Codingbat but it doesn`t work, although it does on the code editor.
def lone_sum(a, b, c):
s = set([a,b,c])
return sum(s)

Categories