Arranging Integers using Conditional statements - python

I was wondering if someone would be able to help me regarding my coding problem. I'm still a beginner and I may have missed something here.
Basically, the instruction says that I need to arrange 3 integers in ascending order.
e.g Input : 5 2 4 ------> Output : 2 4 5
I need to utilize the conditional statements for this. Here is what I've done so far.
a, b, c = input().split()
a = int (a)
b = int (b)
c = int (c)
if a < b and a < c:
smallest = a
elif b < a and b < c:
smallest = b
else:
smallest = c
if a > b and a < c:
middle = a
elif a < b and a > c:
middle = a
elif b > a and b < c:
middle = b
elif b < a and b > c:
middle = b
else:
middle = c
if a > b and a > c:
largest = a
elif b > a and b > c:
largest = b
else:
largest = c
print(smallest, middle, largest)
This is on CodeChum btw, I'm stuck in this because I can't figure out why it doesn't accept the code I did. Basically there are 5 tests that the code needs in order to submit the whole activity. I managed to do test 1-4 but for some reason it fails on test 5.

The problem is that your code does not react well if two numbers are identical. You should replace your strict inequalities with non-strict ones.
a = 3
b = 3
c = 1
if a > b and a < c:
middle = a
elif a < b and a > c:
middle = a
elif b > a and b < c:
middle = b
elif b < a and b > c:
middle = b
else:
middle = c
print(middle) # 1 when it should be 3
As a == b, none of the 4 conditions can be True, and therefore the middle number will always be c.
In order to support the case where a == b, we can add another condition:
elif a == b:
middle = a
else:
middle = c
we can simplify this code by replacing the strict inequalities with non-strict ones (⩽ , <= in Python):
if b <= a < c:
middle = a
elif b >= a > c:
middle = a
elif a < b < c:
middle = b
elif a > b > c:
middle = b
else:
middle = c
We simply said that if a == b, the middle is always a. I also simplified the structure for better readability.

Why don't you simply use sorted function?
This one results in the exact thing you are looking for.
smallest, middle, largest = sorted(map(int, input().split()))
print(smallest, middle, largest)
Note that you don't need the map to int function for this. But you if don't do that, the smallest, middle, largest variables will remain str objects.

As the input is guaranteed to contain exactly 3 numbers (separated by whitespace) you can just do this:
if (inval := input()):
if len(nums := inval.split()) == 3:
try:
lo, mid, hi = sorted(map(int, nums))
print(lo, mid, hi)
except ValueError:
pass

Related

How to make a function which multiplies two values

So, I was writing overly complex answers for simple problems on Codewars as I often do, and one of the problems was,
Multiply two numbers
It wanted me to put:
return a * b
But I wanted to make a function that multiplied two numbers by itself, without the help of the '*' operator or any other thing that multiplied values together.
Pretty easy, I thought. I just add the a value to some empty value b amount of times.
It worked pretty well, up until one of the tests included decimals. I then wrote this to get the average of.. well something. That clearly didn't work:
def multiply(a, b):
leftside = 0
rightside = 0
average = 0
for i in range(int(b)):
leftside += a
for i in range(int(a)):
rightside += b
average = (leftside+rightside) / 2
return average
So basically, what I'm asking is if there's a way to naturally, without any other functions or operators(besides addition and essential things) to multiply values.
If you allow division by 2 like your own attempt does, then I guess this might be decent:
def multiply(a, b):
while b >= 1:
b /= 2
a += a
result = 0
while b:
b += b
a /= 2
if b >= 1:
result += a
b -= 1
return result
Or implementing halving myself, without using division:
def half(x):
result = 0
while x:
y = 0
Y = 2.2250738585072014e-308
while Y + Y <= x:
y = Y
Y += Y
x -= Y
result += y
return result
def multiply(a, b):
while b >= 1:
b = half(b)
a += a
result = 0
while b:
b += b
a = half(a)
if b >= 1:
result += a
b -= 1
return result

What does [b, c][a < b < c]+'000'[a < c:] expression do?

This is the code about to find out dice gamble's prize amount:
a, b, c = map(int, input().split())
if a == b and b == c: #same all of dice numbers
print(10000 + (a * 1000))
elif a == b or b == c: #same two of dice numbers
print(1000 + (b * 100))
elif a == c: #same two of dice numbers
print(1000 + (a * 100))
else: #no same number
print(max(a, b, c)*100)
This is equivalent:
*_, a, b, c=sorted(input())
print(['1'+b, c][a < b < c]+'000'[a < c:])
But i can't understanding about what does
['1'+b, c][a < b < c]
and
'000'[a < c:]
do.
So, I had tried to find out the meaning of
`['1'+b, c][a < b < c]`
I found this is similar with
`c if a<b<c else '1'+b`
but i can't be sure about that.
anyway, about
`'000'[a < c:]`
I tried input a=c to
`print('000'[a < c:])`
It shows 000.
I tried else that input a<c, it shows 00
Anyone can tell me about this expression?
The original is unnecessarily cryptic. It uses the fact that:
int(False) == 0
int(True) == 1
For instance,
'000'[False:] == '000'[0:] == '000'
'000'[True:] == '000'[1:] == '00'
Similarly,
['1' + b, c][False] == ['1' + b, c][0] == '1' + b
['1' + b, c][True] == ['1' + b, c][1] == c
Here's an equivalent rewrite:
prefix = c if a < b < c else '1' + b
suffix = '00' if a < c else '000'
print(prefix + suffix)
a < c will evaluate to either True or False. So you are effectively getting either print('000'[True:]) or print('000'[False:]).
When you have the [] after a string, those will perform a slice on the string. You'd see this in actually practice as something like the following (here's a link for more info:
'abcde'[2] # returns 'c', which, starting from zero, is 2nd item
'abcde'[0] # returns 'a', which is the zero-th item
'abcde'[1:3] # returns 'bc', starting from the 1st item and going to the 3rd, not inclusive of the third
It looks like if you use booleans in such a slice, the False acts as a 0 and True acts as a 1
"abcde"[True] == "abcde"[1] # evaluates to true, these are the same
'abcde'[True] # evaluates to 'b'
"abcde"[False] == "abcde"[2] # evaluates to `False`
"abcde"[True] == "abcde"[2] # evaluates to `False`
"abcde"[False] == "abcde"[0] # evaluates to True, because False is effectively 0 here
So, having a [True:] or [False:] in that string-slice is the same as having [1:] or '[0:]`, which is saying to "give all characters starting with the second (for True/1:) or first (for False/0:) in this string".
The string '000' has length 3. The boolean a < c has value False or True. The operation s[i] for a string s and integer i refers to the i'th element of s, and the operation s[i:] takes the substring of s from index i through the end of s. A boolean value will be converted to an integer in Python as follows: False becomes 0 and True becomes 1.
So, '000'[a < c:] is the same as '000'[0:] if a < c is False, and this is the same as '000'. If a < c is True, then '000'[a < c:] is the same as '000'[1:] which is '00'.

Variable is overwritten in if statement

Write a program to read 3 integers from the user, and calculate the sum of the integers. However, if one of the values is the same as another of the values, it should not count towards the sum.
Enter a: 3
Enter b: 3
Enter c: 3
The sum is 3
The correct answer should be 0, however I realise by my first if statement a has been reassigned to 0 and since by that point a!=c for 0!=3, I am stuck on this testcase
a = int(input("Enter a: "))
b = int(input("Enter b: "))
c = int(input("Enter c: "))
if a == b:
a = 0
b = 0
elif a == c:
a = 0
c = 0
elif b == c:
b = 0
c = 0
print("The sum is", a + b + c)
you could use collections.Counter and only count the values that appear once:
count = Counter((a, b, c))
s = sum(value for value, quantity in count.items() if quantity == 1)
print(f"The sum is {s}")
the problem with your implementation is that if a == b the other two elifs will never be executed. you need change the elifs to ifs.
then you would test a == c again (after having set a to 0). for that approach to work you would have to use temporary variables instead:
tmp_a, tmp_b, tmp_c = a, b, c
if a == b:
tmp_a, tmp_b = 0, 0
if a == c:
tmp_a, tmp_c = 0, 0
if b == c:
tmp_b, tmp_c = 0, 0
print(f"The sum is {tmp_a + tmp_b + tmp_c}")
The problem is that you reassign 0 to values that could be duplicate of other values. You first need to do the comparison between all values at the same time, and then do single comparison.
a = int(input("Enter a: "))
b = int(input("Enter b: "))
c = int(input("Enter c: "))
s = 0
if a == b and a == c:
s = 0
elif a == b:
s = c
elif a == c:
s = b
elif b == c:
s = a
else:
s = a + b + c
print("The sum is ", s)

Finding Greatest Common Divisor through iterative solution (python 3)

I am trying to find the great common divisor by using a function and solving it iteratively. Though, for some reason, I am not sure why I am not getting the right output.
The greatest common divisor between 30 & 15 should be 15, however, my output is always giving me the wrong number. I have a strong feeling that my "if" statement is strongly incorrect. Please help!
def square(a,b):
'''
x: int or float.
'''
c = a + b
while c > 0:
c -= 1
if a % c == 0 and b % c == 0:
return c
else:
return 1
obj = square(30,15)
print (obj)
You should return a value only if you finished iterating all numbers and found none of them a divisor to both numbers:
def square(a, b):
c = a + b
while c > 0:
if a % c == 0 and b % c == 0:
return c
c -= 1
return 1
However, the last return will be unneeded in this case, as c would go from a + b to 1, and mod 1 will always bring a common divisor, so the loop will always terminate with 1, for the worst case.
Also, a number greater than a and b can not be a common divisor of them. (x mod y for y > x yields x), and gcd is the formal name for the task, so I would go with
def gcd(a, b):
for c in range(min(a, b), 0, -1):
if a % c == b % c == 0:
return c
for iterational solution.
You might be interested to know that there is a common recursive solution to the GCD problem based on the Euclidian algorighm.
def gcd(a, b):
if b == 0:
return a
else:
return gcd(b, a % b)
print(gcd(30, 15))
# 15

> returning == in python 3 triangle exercise

I'm new to programming and this is my first time asking a question, so apologies in advance if I'm breaking any protocols. I tried searching for an answer before posting, but I didn't find any matching results.
I'm working my way through Think Python 2, and here is my solution to exercise 5.3, the triangle exercise.
def is_tri():
print('Give me 3 lengths')
a = int(input('first?\n'))
b = int(input('second?\n'))
c = int(input('third?\n'))
if a > b + c or b > a + c or c > a + b:
print('Not a triangle')
else:
print("Yes, it's a triangle")
is_tri()
What I noticed is that if I give 3 answers wherein 2 of the lengths equal the third when added together, i.e. (1,1,2), the program returns Yes. But 2 is not greater than 2. I even added a series of 'and' statements requiring that the sum of any two sides must not equal the third, and it still returns Yes:
if (a > b + c or b > a + c or c > a + b) and (a != b + c and b != a + c and c != a + b):
The author mentions that the sum of two sides equaling the third is a 'degenerate triangle', perhaps anticipating this outcome. But why? Don't the '>' and '>=' operators provide different functions? Am I missing something? How can I constrain the operator to exclude degenerate triangles?
If you need to declare that triangles that have the largest side equal to the sum of the others are invalid you are using the wrong operator, you should use == in conjunction to >, so your condition would look like:
if (a > b + c or a == b + c) or (b > a + c or b == a + c ) or (c > a + b or c == a + b):
Which is exactly the same as to making it like this:
if a >= b + c or b >= a + c or c >= a + b:
One nice way of doing it is sorting the list to get the largest element and then comparing to the sum of the others using slices, for this you would need the inputs to be in a list:
triangle_sides = [int(input('first?\n')), int(input('second?\n')), int(input('third?\n'))]
triangle_sides = sorted(triangle_sides, reverse=True)
if triangle_sides[0] >= sum(triangle_sides[1:]):
print("Absolutelly not a triangle")
else:
print("Congratulations, its a triangle")
I would also recommend you to get your inputs from outside the function, separating the "user interface" from the logic, your script would look like:
def is_valid_triangle(triangle_sides):
triangle_sides = sorted(triangle_sides, reverse=True)
if triangle_sides[0] >= sum(triangle_sides[1:]):
return False
return True
def triangle_validator():
print('Give me 3 lengths')
triangle_sides = [
int(input('first?\n')),
int(input('second?\n')),
int(input('third?\n'))
]
if is_valid_triangle(triangle_sides):
print('Yes, it\'s a triangle')
else:
print('Not a triangle')
if __name__ == '__main__':
triangle_validator()
Your condition clearly states that the line lengths do not form a triangle only if one length is strictly greater than the sum of the other two. That's not the condition you're looking for. You want to disqualify the input if one is greater or equal to the sum of the other two.
This would work:
if a >= b + c or b >= a + c or c >= a + b:

Categories

Resources