I am taking my first python course, this should be an easy thing but I can't get it right. I have done a search, but I guess the keyword are just too common.
So, I did an assignment where I had to write a function that squares a number. I did it successfully with just:
def square(x):
'''x: int or float.'''
return x * x
I have tried with other functions just to try different ways of doing the exercise, if I try to incorporate some loop like:
def square(x):
'''x: int or float.'''
for number in range(x):
result = x * x
return result
It only works for integers(so square(5) gives me 25, but square (5.0) gives me 'TypeError: range() integer end argument expected, got float'. How can I get this function to square floats or negative numbers? Thanks in advance
First question
It's only valid for integers(so square(5) gives me 25, but square (5.0) gives me 'TypeError: range() integer end argument expected, got float'.
Answer
Because range function is defined as taking only integer data. See Python documentation.
Example:
>>> range(5)
[0, 1, 2, 3, 4]
>>> range(5.0)
TypeError: range() integer end argument expected, got float.
>>> range("5")
TypeError: range() integer end argument expected, got str.
>>> range(0, 5)
[0, 1, 2, 3, 4]
>>> range(0, 5.0)
TypeError: range() integer end argument expected, got float.
Second question
How can I get this valid for floats or negative numbers?
Answer
I don't know what "valid" means. It depends on what you are trying to do. So please comment or update your question.
The loop in your second example doesn't actually do anything: it overwrites the value of result every time with the same number, and doesn't even use the loop counter.
If you want an alternate way to compute a square, a method for integers only that uses loops would be this:
def square2(x):
x = int(math.fabs(x))
result = 0
for i in range(x):
result += x
return result
This takes the sum of x added together x times (i.e., converts the multiplication into addition). It handles negative integers as well, but not floats. The reason this doesn't work for floats is that you can't count from 0 to an arbitrary float (real numbers are uncountable).
Honestly, your first solution in your question is the straightforward, simple, and therefore (IMO) the best one.
Related
I'm still new to generators in python. I was trying out one on my own and tried to something really simple:
def fib(a):
... if a==0 or a==1:return 1
... yield fib(a-1)+fib(a-2)
print(list(fib(5))
This code gave me this error:
TypeError: unsupported operand type(s) for +: 'generator' and 'generator'
Can't generators be used in this manner?
Calling a generator function doesn't produce the next value. It produces a generator object, a specialist version of an iterator object. You have, in effect, something that wraps a paused function.
To get another value from that function, you'd have to call next(iterator) on the object or use something like list(iteratort) or for ... in iterator to loop over the object and get the values out. See What does the "yield" keyword do? for more details.
So here, the you'd have to use next(fib(a-1)) + next(fib(a-2)) to get the two recursive values out. That'll also fail, because your termination case (a == 0 or a == 1) uses return (translated into the value of a StopIteration exception) and not yield; you'd have to fix that too.
And this highlights why your recursive function should not be a generator function. Your function doesn't produce a series of values to iterate over. There's just one result mfor a given argument value. You'd be far better off to just use return and not yield.
If you wanted to generate a sequence of fibonacci numbers, the function argument would need to be seen as a limit; "give me the first n fibonacci numbers". The following iterative function does that:
def first_n_fibonacci(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
yield a
This would give you a list of the first n fibonacci numbers, as a generator:
>>> f = first_n_fibonacci(5)
>>> f
<generator object first_n_fibonacci at 0x10b2c8678>
>>> next(f)
1
>>> next(f)
1
>>> list(f)
[2, 3, 5]
or you could use the argument to produce all fibonacci values up to a limit, or to produce an endless generator of fibonacci numbers. None of those would require recursion, a loop like the above suffices.
Generators are meant to be used for iterations, and yet by adding two of the returning values from fib you are trying to use it as a scalar value, which is confirmed by your terminal condition (where a equals to 0 or 1) also returning a scalar value.
You should simply use return in this case.
def fib(a):
if a==0 or a==1:return 1
return fib(a-1)+fib(a-2)
print(fib(5))
If you do want to use a generator, you need to think about outputting a sequence, and not a single value. Do you want your fib(a) to output the ath fib number or the the 1st, 2nd, 3rd, 4th, 5th ... ath fib number? If the latter, then generators are good for this.
Here is an example generator for the Fibonacci numbers from the 1st to the nth number.
def fib(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
I am trying to evaluate power series using python. series => e^x = 1+ x+ x^2/2! + x^3/3!...x^n/n!
I am getting this error ''int' object has no attribute 'extend'.
My code:
import math
print('give x')
x = float(input())
n =100
k = 0
list = (1)
while 0<x<1:
list.extend([math.pow(x,K+1))])
k = k+1
if x==n:
break
print(sum(list))
Please help!
There are multiple problems with your code.
Firstly, you are attempting to create a list with (1) - that just creates the integer object 1, the parentheses have no effect here. To create a list containing 1 you need [1]. And you shouldn't use the names of Python built-ins (like list) as variable names - not only is it confusing to other people who may read your code it makes the built-in inaccessible, which can lead to mysterious bugs.
K is not the same as k.
Your while 0<x<1: test does't make much sense; FWIW, the Taylor series for ex converges for all values of x.
Your if x==n: test should be if k==n:, although it'd be better to use a for loop with range (or maybe xrange in Python 2).
You don't need to save the terms in a list - just add them as you go.
You don't need math.pow - x**k calculates the same thing as math.pow(x, k), but even that's unnecessary here: you should just keep track of the previous term and multiply it by x on each loop.
You forgot the /n!. Once again, you don't really need to compute the factorial (or call the math.factorial function) since you can just divide the previous term by k.
Hopefully, that's given you enough clues to fix your code. I won't provide working code at this stage, since I suspect this is a homework problem. Note that the math module has an exp function which you can use to test the accuracy of your power series calculations.
A list literal is created with square brackets, []. You can use parentheses, (), for grouping or for creating a tuple. In the case of list = (1), they are being used for grouping, so this is the same as list = 1. (A tuple with one element is created with mytuple = (1,) or just mytuple = 1,.)
At this point, I'll mention that naming one of your variables list masks the built-in function list, so after you do that you can't access that function anymore without some effort. It's best to name your object something else, like lst.
A list's extend() method adds all the elements from the passed list onto the object you're accessing, so if mylist was [1, 2, 3], mylist.extend([4, 5]) would result in mylist becoming [1, 2, 3, 4, 5]. However, you only have one object to add, so it makes more sense to use append(), which adds the passed object to the given list.
x = float(input('Give x: ')) # the input function can be passed a prompt string
n = 100
k = 0
lst = [1] # changed name, created a list
while 0<x<1:
list.append(x**(k+1)) # you can just use the ** operator if you want
# also, k isn't K
k = k+1
if x==n: # x is never changed, so your loop either never runs
# or goes forever
break
print(sum(lst))
Note the while loop that will either never be entered or never finish. You'll have to take another look at your program's logic.
need help with this, i tried something but it didn't work for some reason. I need some help to figure it out.
def F(n):
if n == 0: return 0
elif n == 1: return 1
else: return F(n-1)+F(n-2)
F('3')
and here is the original problem- Write a function called fib which takes as a parameter an integer, n, and returns the nth number in the Fibonocci sequence (see definition below). If n is zero or a negative number, your function should return an error message in the form of a string "Error: Invalid input.".
The Fibonocci sequence is 1, 1, 2, 3, 5, 8, 13, 21, ... where the first two numbers are 1, and each number beyond that is calculated as the sum of the previous two numbers (2 = 1+1, 3 = 2+1, 5 = 3+2, 8=5+3, etc).
i guess the problem is that you use string instead of integer.
try F(3) instead of F('3')
or give more information about the error you get
First, for the invalid numbers error you are supposed to print out, I would suggest adding another if statement in. Below shows an example of how you could set any negative number to return an error message.
if n < 0: return "Error: Invalid Input"
For the F function, it goes back to data types. When you put in quotes around something, that specifies an actual string. When you just have a number, it will be an integer data type. For this, we want an integer data type since we want to do math operations on our number. This is why you should remove the quotes.
errors = int(0)
for i in range(len(expectedData)):
if data[i] != expectedData[i]:
errors += int(binary_compare(data[i], expectedData[i]))
return errors
I have the above code which I am trying to use to calculate some integer (number of errors) for some data. I have casted everything I can see possible as an integer, yet the line "errors += ..." still appends the value, rather than adds it.
For example, if my answer should be 7, I might get 500002. (5 + 0 + 0 + .. + 2). I have never run into this before. The function binary_compare is returning an integer as well, but I'm completely in the dark as to why this isn't working.
python is not javascript
it's no way to get concatenated strings instead of math sum, when you do count += value starting with count = 0. if you try to add a string to integer, exception is raised:
>>> x = 0
>>> x += "1"
TypeError: unsupported operand type(s) for +=: 'int' and 'str'
to compare values of which you don't know whether they are strings or integers, i'd use
str(data[i]).strip() == str(expectedData[i]).strip()
for noninteger-proof math sum, you might want to do something like this
try:
value = int(expectedData[i])
except:
value = 0
count += value
I think the error is outside of your code, but anyway, in Python, list operations are seldom done with loops, as this focuses on the implementation rather on the purpose. List comprehension, generators etc are preferred, and there are also many built-in and standard library functions for common tasks.
In your case, I would write the function as
return sum(binary_compare(x, y) for x, y in zip(data, expectedData) if x != y)
If you are using Python 2.x, itertools.izip should be used instead of zip.
Why do you need to use the function 'str' in the following code?
I am trying to count the sum of digits in a number.
My code
for i in number:
sum(map(int, str(i))
where number is the following array
[7,79,9]
I read my code as follows
loop though the array such that
count sum of the integer digits
by getting given digits in a number by map increasingly
such that each object (given number) is converted to String // This does not make sense
Manual says this for str
Type: type
Base Class: <type 'type'>
String Form: <type 'str'>
Namespace: Python builtin
Docstring:
str(object) -> string
Return a nice string representation of the object.
If the argument is a string, the return value is the same object.
Given 79 you need to get [7, 9] in order to sum up this list.
What does it mean to split a number into digits? It means to represent the number in a numerical system with some base (base 10 in this case). E. g. 79 is 7 * 10**1 + 9 * 10**0.
And what is the simplest (well, at least in this context) way to get such a representation of a number? To convert it to a string of decimals!
Your code does exactly that:
>>> str(79)
'79'
# Another way to say this is [int(c) for c in str(79)]
>>> map(int, str(79))
[7, 9]
>>> sum(map(int, str(79)))
16
What happens when you try that code without using str()?
The str() is used to convert the integer into a sequence of characters, so that map() can iterate over the sequence. The key point here is that a "string" can be treated as a "sequence of characters".
Why do you need to use the function 'str' in the following code?
Because map takes an iterable, like a list or a tuple or a string.
The code in question adds upp all the numbers in an integer. And it does it by a little clever hack. It converts the number into a sequence of numbers by doing
map(int, str(i))
This will convert the integer 2009 to the list [2, 0, 0, 9]. The sum() then adds all this integers up, and you get 11.
A less hacky version would be:
>>> number = [7,79,9]
>>> for i in number:
... result = 0
... while i:
... i, n = divmod(i, 10)
... result +=n
... print result
...
7
16
9
But your version is admittedly more clever.