How to use float variable with range function in python? - python

Description:
I have three variable a, x and y. I want to apply the following, if variable a in range(x, y) print the a variable
Code:
a = "0.50"
x = "-14.40"
y = "0.50"
for a in range(int(x), int(y)):
print a
Error (of course):
ValueError: invalid literal for int() with base 10: '-14.40'
Pythonista i need your help here please!!

The Python 2 range function is irrelevant for this task. You just need to convert those strings to floats and do simple comparison tests. Eg,
a = "0.50"
x = "-14.40"
y = "0.50"
afloat = float(a)
if float(x) <= afloat and afloat <= float(y):
print a
output
0.50
This can be written more simply (and more efficiently) using Python's comparison chaining.
a = "0.50"
x = "-14.40"
y = "0.50"
if float(x) <= float(a) <= float(y):
print a
FWIW, in Python 3, the range object can be useful for testing membership of a range, but it wouldn't be useful for your case. Eg,
>>> r = range(1, 10, 2)
>>> list(r)
[1, 3, 5, 7, 9]
>>> 3 in r
True
>>> 4 in r
False
>>> 3.5 in r
False

From the comments
i need to check if a in range of x and y or not.
Then do
a = "0.50"
x = "-14.40"
y = "0.50"
if float(x) <= float(a) <= float(y): # checks a is between x and y (inclusive)
# do something
range does something very different. It is for making iterators which we can use in for loops, like this:
for i in range(4):
print(i * 2)
0
2
4
6

You can use numpy arange.
import numpy as np
r = np.arange(-14.4,0.5, 0.5)
def isinside(x):
if x in r:
print ("x")
else:
print ("x no in a")
isinside(-12)
returns
x no in a
If you want to print the whole serie
print ([round(x) for x in r])# round to avoid long numbers
Some more information https://pynative.com/python-range-for-float-numbers/

Related

Project Euler Problem 2 in Python with Error Message

I am a complete beginner in coding and was trying problems from Project Euler in Python. Could anyone please explain what is wrong with my code?
Problem: Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
a = []
x = 1
y = 2
for y in range (1, 400000):
if x % 2:
a.append(x)
x = y, y = x + y
print(sum(a))
I received the error message "cannot unpack non-iterable int object". What does this message mean and how to avoid it?
You get that error because you have the line x = y, y = x + y which is interpreted as an attempt to unpack values from an iterable into y, y, so you need to have a new line between x = y and y = x + y.
However since x is assigned with the value of y before y is updated, the better option is to change the line to x, y = y, x + yas JackTheCrab suggested in a comment.
Look the below example as well to explain the error:
price, amount = ["10$", 15] #iterable that can be unpacked
price, amount = 15 # this is just an int and this row will throw error "Cannot unpack non-iterable int object"
x = y, y = x + y
When i take away the addition from the end and the assignment from the beginning, the error still is there.
y, y = x
Output : an error. about non-iterable int ! Because you can unpack an iterable.
iterable = [0, 1, 2]
zero = iterable[0]
one = iterable[1]
two = iterable[2]
is not very good (sorry for my bad english ...) to use, because you have to type iterable[n] again and again. That's why you can unpack such iterables like this:
iterable = [0, 1, 2]
zero, one, two = iterable
This will produce the same result as the above long version.
Back to your code,
x = y, y = x + y
the python interpreter will first work on the assignment (x = ...). To resolve it, it tries to unpack x + y into two values, but this is not possible of course.
To declare two variables on one line, you have to separate the assignments with a colon ;, not a comma. But when you do just that, x will have the same value as y at the beginning, and so y will then be the double of itself, which surely is not what you wanted. Maybe you should do it like this ?
a = []
x = 1
y = 2
for y in range (1, 400000):
if x % 2:
a.append(x)
x, y = y, x + y
# above is equivalent to
# temp = y
# y = x + y
# x = temp
print(sum(a))

Why are lists created by a function not iterable

I'm new to python and don't understand much. I created a function that takes a number and puts all the integers which lead up to that number, including that number, into a list. Or so I thought, turns out I cant actually use the created list as a list. Any ideas on how I can make it useable?
def break_up(x):
"""breaks up the the integers adding up to a number x, starting at 1. Works for any positive number or 0"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
print(a)
As people have commented, your indentation is incorrect, but in addition you are not actually calling the function.
The function needs to return an object. An object created in a function stays there and is not visible outside (unless it is global) - this is called encapsulation and is an important programming technique which enables functions to be used anywhere.
Note that even the multi-line comment has to be indented (and I have made it multi-line)
Here is my version of your program:
def break_up(x):
"""
breaks up the the integers adding up to a number x, starting at 1.
Works for any positive number or 0
"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
return a # <<<< added
# At this point, the name 'a' is not visible
thing = break_up(5)
print(thing)
# or
print(break_up(5))
Just for fun, try this:
$ python3 -i gash.py
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
>>> help(break_up)

Pandas conditional: How to use an If or While statement with str contains [duplicate]

Is there a numpy way of doing
n = [x-t if x > 0 else x for x in nps]
similar to this
n = np.array(a)
n[np.abs(n) < t] = 0
something like this perhaps?
n[n > 0] = n-t
Can't test now, but try
np.where(n > 0, n - t, n)
See documentation

Subselection using np.logical_and in Numpy

I plot(x,y) a chart and want to return True when for x ranging from A to B y is larger than C ("there exists x in interval such that y(x) > C). The code below does not work. How can I do it?
d_for_hours=density[np.logical_and(y>C,x>=A, x <=B)].all()
Exemplary output:
for C = 0.02 and A = 9 and B = 13, the output should be True
for C = 0.05 and A = 9 and B = 13, the output should be False
You want to use any rather than all to check if y has any value above C. Before that, you need to restrict y to the indices of x that match the condition (between A and B):
# create data
x = np.array(range(20))
y = np.array(19 * [0] + [1])
(y[np.logical_and(x>=9, x<=13)] >= 0.05).any() # False
(y[np.logical_and(x>=9, x<=20)] >= 0.05).any() # True

How to stop a loop?

def sum_div(x, y):
for k in range(x,y+1):
for z in range(x,y+1):
sx = 0
sy = 0
for i in range(1, k+1):
if k % i == 0:
sx += i
for j in range(1, z+1):
if z % j == 0:
sy += j
if sx == sy and k!= z:
print "(", k ,",", z, ")"
x = input("Dati x : ")
y = input("Dati y : ")
sum_div(x, y)
How do I stop the looping if the value of z == y?
The loops print a pair of numbers in a range from x to y, but when it hit the y value the loop prints a reverse pair of numbers that I don't need it to.
The break command will break out of the loop. So a line like this:
if (z == y):
break
should do what you want.
What you're think you are asking for is the break command, but what you're actually looking for is removal of duplication.
Your program lacks some clarity. For instance:
for i in range(1, k+1):
if k % i == 0:
sx += i
for j in range(1, z+1):
if z % j == 0:
sy += j
These two things are doing essentially the same thing, which can be written more cleanly with a list comprehension (in the REPL):
>>> def get_divisors(r: int) -> list:
... return [i if r % i == 0 else 0 for i in range(1, r+1)]
...
...
>>> get_divisors(4)
>>> [1, 2, 0, 4]
>>> sum(get_divisors(4))
>>> 7
Your line:
while y:
... will infinitely loop if you find a match. You should just remove it. while y means "while y is true", and any value there will evaluate as true.
This reduces your program to the following:
def get_divisors(r: int) -> list:
return [i if r % i == 0 else 0 for i in range(1, r+1)]
def sum_div(x, y):
for k in range(x,y+1):
sum_of_x_divisors = sum(get_divisors(k)) # Note this is moved here to avoid repeating work.
for z in range(x,y+1):
sum_of_y_divisors = sum(get_divisors(z))
if sum_of_x_divisors == sum_of_y_divisors and k!= z:
print("({},{})".format(k, z))
Testing this in the REPL it seems correct based on the logic of the code:
>>> sum_div(9,15)
(14,15)
(15,14)
>>> sum_div(21, 35)
(21,31)
(31,21)
(33,35)
(35,33)
But it's possible that for sum_div(9,15) you want only one of (14,15) and (15,14). However, this has nothing to do with breaking your loop, but the fact that what you're attempting to do has two valid values when k and z don't equal each other. This is demonstrated by the second test case, where (33,35) is a repeated value, but if you broke the for loop on (21,31) you would not get that second set of values.
One way we can account for this is by reordering when work is done:
def sum_div(x, y):
result_set = set() # Sets cannot have duplicate values
for k in range(x,y+1):
sum_of_x_divisors = sum(get_divisors(k))
for z in range(x,y+1):
sum_of_y_divisors = sum(get_divisors(z))
if sum_of_x_divisors == sum_of_y_divisors and k!= z:
result_set.add(tuple(sorted((k,z)))) # compile the result set by sorting it and casting to a tuple, so duplicates are implicitly removed.
for k, z in result_set: # Print result set after it's been compiled
print("({},{})".format(k, z))
And we see a correct result:
>>> sum_div(9,15)
(14,15)
>>> sum_div(21,35)
(21,31)
(33,35)
Or, the test case you provided in comments. Note the lack of duplicates:
>>> sum_div(10,25)
(16,25)
(14,15)
(15,23)
(10,17)
(14,23)
Some takeaways:
Break out functions that are doing the same thing so you can reason more easily about it.
Name your variables in a human-readable format so that we, the readers of your code (which includes you) understands what is going on.
Don't use loops unless you're actually looping over something. for, while, etc. only need to be used if you're planning on going over a list of things.
When asking questions, be sure to always include test input, expected output and what you're actually getting back.
The current best-practice for printing strings is to use the .format() function, to make it really clear what you're printing.

Categories

Resources