I am new to python! Done my studying, gone through several books and now attempting pyschools challenges. Done Variables and data types successfully but Question 7 of Topic 2 (Functions) is giving me hell.
I am using Eclipse with Python (ver 3.2). in my eclipse, I get the answers 100, 51 and 525. Those are the same answers pyschools expects but it shows that my function returns 100, 0 and 500.
Here is the question (Hope am allowed to post it here!):
Write a function percent(value, total) that takes in two numbers as arguments, and returns the percentage value as an integer.
And below is my function
def percent (value, total):
a = value
b = total
return(int((a / b) * 100))
percent(70, 70)
percent(46, 90)
percent(63, 12)
Can anyone tell me what pyschools really want me to do or where am going wrong?
Thanks!
You're using Python 3.x and they're using Python 2.x. In Python 2.x, the / operation is always an integer division when the arguments are integers. 1/2 is 0. So, use float() to change one of your arguments to a floating-point number, such as int((float(a) / b) * 100). Then a/b will have a fractional part.
Or, assuming they are using a recent version of Python 2.x, you can just add this to the beginning of your script and it should work on the site:
from __future__ import division
As an aside, why are you assigning your input parameters to variables? They're already variables. If you want them named a and b, just receive them that way:
def percent(a, b):
return int((float(a) / b) * 100)
because it is using python 2.x you need to atleast convert one value to float
def percent(number, total):
return int((float(number)/total) * 100)
this will work fine
Python performs mathematical operations on integers with strictly integer math, truncating fractional parts.
To avoid that, multiply one of the inputs by 1.0 before dividing.
You can use the truncating divide, like this:
def percent(value, total):
return value * 100 // total
Advantages:
(0) Works with all Pythons from 2.2 onwards.
(1) The reader knows what that one line does without having to guess what version of Python is being run and without having to inspect the start of the module for from __future__ magic.
(2) Avoids any potential floating-point problems.
(3) Avoids using float and int i.e. saves two (relatively expensive) function calls.
Note carefully: // works on float objects as well as int objects. The question says that the args are "numbers" (can include float objects) and the result should be an "integer" (not necessarily an int object). That gives you considerable licence.
>>> percent(63.001, 11.9999)
525.0 # That's an integer
If they insist on the return value being an int object, then of course you'll need an int().
Related
To keep things simplistic, consider the Python function:
def to_string(value):
return str(value)
Since we cannot define data types of parameters in Python (as for as I know), when I pass 1/2 to above function, it automatically converts 1/2 to 0.5 and then returns string '0.5'. How do I make it return '1/2'? How do I force Python to treat arguments to be of certain data type, no matter how they "appear"?
Here (in python 3) 1/2 is evaluated to 0.5 before being even passed into the function. For this specific example you have lost the information, due to possible float accuracy errors, before the function is even called; In theory you can get back to 1/2 from 0.5 but you should not rely on this float manipulation. In order to not lose this accuracy here you should probably treat a fraction as two pieces of integer information as it really is, instead of one float.
from fractions import gcd
def to_string(n, d):
g = gcd(n, d)
return str(n//g) + "/" + str(d//g)
If what you are asking is specifically about fractions then a class built around this idea is probably your best bet. If your example is not explanatory then (famously) python does not have type enforcement. However you can read here https://docs.python.org/3/library/typing.html about modernisation of this idea and decorators.
I was recently working with Python and wanted to use another way of finding square roots. For example I wanted to find square root of n with Newton-Raphson approximation. I need to overload the overload the ** (only when you raise a number to 0.5),o perator as well as math.sqrt(), because I have several older projects that could be sped up by doing so and replacing all math.sqrt() and **(0.5) with another function isn't ideal.
Could this be done in Python?
Is it possible to overload either ** or math.sqrt?
Any helpful links are also much appreciated.
def Square_root(n):
r = n/2
while(abs(r-(n/r)) > t):
r = 0.5 * (r + (n/r))
return r
print(2**(0.5)) ## changes to print(Square_root(2))
print(math.sqrt(2)) ## that also becomes print(Square_root(2))
In short: you can't change the behavior of __pow__ for built-in types.
Long answer: you can subclass the float, but it will require additional coding and refactoring of the input values of the program, to the new float class with overwritten operators and functions.
And you can overwrite the math.sqrt, but this is not recommended:
import math
math.sqrt = lambda x, y: print(x, y)
math.sqrt(3, 2)
# 3 2
This will require the custom function to have the same signature.
If you really want to overload languages int and float objects - you can use variants of magic functions. In order to be consistent, you'll have to write a lot of code.
A lot of work. Python is for lazy people - if you like to write a lot, stick to Java or C++ :)
I am new to SAGE and am having a problem with something very simple. I have the following code:
delay = float(3.5)
D = delay%1.0
D
But this returns the value -0.5 instead of the expected 0.5. What am I doing wrong?
If I change delay to be delay = float(2.5), I get the right answer, so I don't know why it isn't consistent (I am sure I am using the modulo wrong somehow).
I think that this question will answer things very well indeed for you.
However, I don't know why you are using float in Sage. Then you could just use Python straight up. Anyway, the % operator is tricky to use outside of integers. For example, here is the docstring for its use on Sage rational numbers.
Return the remainder of division of self by other, where other is
coerced to an integer
INPUT:
* ``other`` - object that coerces to an integer.
OUTPUT: integer
EXAMPLES:
sage: (-4/17).__mod__(3/1)
1
I assume this is considered to be a feature, not a bug.
I've been experimenting with the standard python math module and have come across some subtle difficulties. For example, I'm noticing the following behavior concerning indeterminate forms:
0**0
>>> 1
def inf():
return 1e900
# Will return inf
inf()**inf()
>>> inf
And other anomalies of the sort. I'm writing a calculator, and I'd like to have it be mathematically accurate. Is there something I can do about this? Or, is there some way to circumvent this? Thanks in advance.
There's nothing wrong with your first example. 0**0 is often defined to be 1.
The second example is all to do with precision of doubles. 1E900 exceeds the maximum positive value of a (most likely 64-bit) double. If you want doubles outside of that range, you'll have to look into libraries. Fortunately Python has one built-in: the decimal module.
For example:
from decimal import Decimal
d = Decimal('1E900')
f = d + d
print(f)
>>> 2E900
According to Wolfram (quoting Knuth) while 0**0 is indeterminate, it's sometimes given as 1. This is because holding the statement 'x**0 = 1' to be true in all cases is in some cases useful. Even more interestingly Python will consider NaN**0 to be 1 as well.
http://mathworld.wolfram.com/Power.html
In the case of infinity**infinity, you're not really dealing with the mathematical concept of infinity here (where that would be undefined), but rather a number that's too large and has overflowed. As such all that statement is saying is that a number that's huge to the power of another number that's huge is still a number that's huge.
Edit: I do not think it is possible to overload a built in type (such as float) in Python so overloading the float.__pow__(x,y) operator directly. What you could possibly do is define your own version of float.
class myfloat(float):
def __pow__(x,y):
if(x==y==0):
return 'NaN'
else:
return float.__pow__(x,y)
m = myfloat(0)
m**0
Not sure if that's exactly what you're looking for though.
Well returning NaN for 0**0 is almost always useless and lots of algorithms avoid special cases if we assume 0**0 == 1. So while it may not be mathematically perfect - we're talking about IEEE-754 here, mathematical exactness is really the least of our problems [1]
But if you want to change it, that's rather simple. The following works as expected in Python 3.2:
def my_pow(x, y):
if y == 0: return 'NaN'
return float.__pow__(float(x), y)
pow = my_pow
[1] The following code can theoretically execute the if branch with x86 CPUs (well at least in C and co):
float x = sqrt(y);
if (x != sqrt(y)) printf("Surprise, surprise!\n");
Why is python telling me "TypeError: pow expected 2 arguments, got 3" despite it working in IDLE (sometimes it tells me that in IDLE as well)? im simply doing pow(a,b,c). my program is very short and i do not change the definition of pow at any time since i need to use it for some exponentiation.
NOTE: This is the pow from __builtin__, not Math
Built-in pow takes two or three arguments. If you do from math import * then it is replaced by math's pow, which takes only two arguments. My recommendation is to do import math, or explicitly list functions you use in import list. Similar issue happens with open vs. os.open.
If you are using math functions a lot and the three parameter version of pow infrequently a way around this in python 2.7 is to import __builtin__ and call __builtin__.pow for the 3 paramete
http://docs.python.org/release/2.6.5/library/functions.html
pow(x, y[, z]) Return x to the power
y; if z is present, return x to the
power y, modulo z (computed more
efficiently than pow(x, y) % z). The
two-argument form pow(x, y) is
equivalent to using the power
operator: x**y.
The arguments must have numeric types.
With mixed operand types, the coercion
rules for binary arithmetic operators
apply. For int and long int operands,
the result has the same type as the
operands (after coercion) unless the
second argument is negative; in that
case, all arguments are converted to
float and a float result is delivered.
For example, 102 returns 100, but
10-2 returns 0.01. (This last
feature was added in Python 2.2. In
Python 2.1 and before, if both
arguments were of integer types and
the second argument was negative, an
exception was raised.) If the second
argument is negative, the third
argument must be omitted. If z is
present, x and y must be of integer
types, and y must be non-negative.
(This restriction was added in Python
2.2. In Python 2.1 and before, floating 3-argument pow() returned
platform-dependent results depending
on floating-point rounding accidents.)
Perhaps you're violating the bold portion?