Subtract Unless Negative Then Return 0 - python

I'll preface with, this is solely to satisfy my curiosity rather than needing help on a coding project. But I was wanting to know if anyone knows of a function (particularly in python, but I'll accept a valid mathematical concept) kind of like absolute value, that given a number will return 0 if negative or return that number if positive.
Pseudo code:
def myFunc(x):
if x > 0:
return x
else:
return 0
Again, not asking the question out of complexity, just curiosity. I've needed it a couple times now, and was wondering if I really did need to write my own function or if one already existed. If there isn't a function to do this, is there a way to write this in one line using an expression doesn't evaluate twice.
i.e.
myVar = x-y if x-y>0 else 0
I'd be fine with a solution like that if x-y wasn't evaluated twice. So if anyone out there has any solution, I'd appreciate it.
Thanks

One way...
>>> max(0, x)

This should do it:
max(x-y, 0)

Sounds like an analysis type question. numpy can come to the rescue!
If you have your data in an array:
x = np.arange(-5,11)
print x
[-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10]
# Now do your subtraction and replacement.
x[(x-y)>0] -= y
x[(x-y)<0] = 0
If I understand your question correctly, you want to replace values in x where x-y<0 with zeros, otherwise replace with x-y.
NOTE, the solution above works well for subtracting an integer from an array, or operating on two array of equal dimensions. However, Daniel's solution is more elegant when working on two lists of equal length. It all depends on your needs (and whether you want to venture into the world of numpy or not).

An alternative expression would be
x -= min(x, y)

Related

Initialize min variable when dealing with big values in Python [duplicate]

This question already has an answer here:
Python - np.inf not larger than number
(1 answer)
Closed 2 years ago.
I have some code where I need to find minimum of something.
So I do:
min_val = np.inf
for e in elements:
if e<min_val:
min_val = e
The problem with that is that some of my elements are REALLY big, and the if statement returns False.
For example:
np.inf > 1e999
>>> False
Now I could do something like
min_val = elements[0]
and afterwards iterate from elements[1], but isn't there a more elegant way of doing this (This will require me to do further checkings, like if elements is not empty, if elements[0] is not inf etc.).
Isn't there a real inf in python (which should simply return True to any "inf>finite number" condition?).
Now, this question is not duplicate to the fact that 1e999==np.inf.
The "duplicate" question explains the problem. Now I need to resolve it.
To put it simple
How do I find the minimum of [1e999, 1e310]?
np.inf is a real inf, but any float larger than 1e308 is going to be treated like infinity. Therefore you're testing if np.inf > np.inf, and it treats it as not greater than itself (perhaps mathematically it doesnt completely make sense).
One solution when it comes to the comparison is to use np.inf >= 1e999 will return True.
Other solution is to use np.min function to find a minimum of an array.
EDIT :
From the comments below, I understand your question to be "How do I work with numbers greater than 1e309".
I would advise you to take a look at
this question on quora.
It gives different solution to your problem.
Else, your problem is impossible to solve using only python and "classic" numbers.
import numpy as np
a = 1e999
a == np.inf
>>> True
The problem is that all number above 1e309 (roughly) are equals to np.inf

How can I get my function to add together its output?

So this is my line of code so far,
def Adder (i,j,k):
if i<=j:
for x in range (i, j+1):
print(x**k)
else:
print (0)
What it's supposed to do is get inputs (i,j,k) so that each number between [i,j] is multiplied the power of k. For example, Adder(3,6,2) would be 3^2 + 4^2 + 5^2 + 6^2 and eventually output 86. I know how to get the function to output the list of numbers between i and j to the power of K but I don't know how to make it so that the function sums that output. So in the case of my given example, my output would be 9, 16, 25, 36.
Is it possible to make it so that under my if conditional I can generate an output that adds up the numbers in the range after they've been taken to the power of K?
If anyone can give me some advice I would really appreciate it! First week of any coding ever and I don't quite know how to ask this question so sorry for vagueness!
Question now Answered, thanks to everyone who responded so quickly!
You could use built-in function sum()
def adder(i,j,k):
if i <= j:
print(sum(x**k for x in range(i,j+1)))
else:
print(0)
The documentation is here
I'm not sure if this is what you want but
if i<=j:
sum = 0
for x in range (i, j+1):
sum = sum + x**k #sum += x**k for simplicity
this will give you the sum of the powers
Looking at a few of the answers posted, they do a good job of giving you pythonic code for your solution, I thought I could answer your specific questions:
How can I get my function to add together its output?
A perhaps reasonable way is to iteratively and incrementally perform your calculations and store your interim solutions in a variable. See if you can visualize this:
Let's say (i,j,k) = (3,7,2)
We want the output to be: 135 (i.e., the result of the calculation 3^2 + 4^2 + 5^2 + 6^2 + 7^2)
Use a variable, call it result and initialize it to be zero.
As your for loop kicks off with x = 3, perform x^2 and add it to result. So result now stores the interim result 9. Now the loop moves on to x = 4. Same as the first iteration, perform x^2 and add it to result. Now result is 25. You can now imagine that result, by the time x = 7, contains the answer to the calculation 3^2+4^2+5^2+6^2. Let the loop finish, and you will find that 7^2 is also added to result.
Once loop is finished, print result to get the summed up answer.
A thing to note:
Consider where in your code you need to set and initialize the _result_ variable.
If anyone can give me some advice I would really appreciate it! First week of any coding ever and I don't quite know how to ask this question so sorry for vagueness!
Perhaps a bit advanced for you, but helpful to be made aware I think:
Alright, let's get some nuance added to this discussion. Since this is your first week, I wanted to jot down some things I had to learn which have helped greatly.
Iterative and Recursive Algorithms
First off, identify that the solution is an iterative type of algorithm. Where the actual calculation is the same, but is executed over different cumulative data.
In this example, if we were to represent the calculation as an operation called ADDER(i,j,k), then:
ADDER(3,7,2) = ADDER(3,6,2)+ 7^2
ADDER(3,6,2) = ADDER(3,5,2) + 6^2
ADDER(3,5,2) = ADDER(3,4,2) + 5^2
ADDER(3,4,2) = ADDER(3,3,2) + 4^2
ADDER(3,3,2) = 0 + 3^2
Problems like these can be solved iteratively (like using a loop, be it while or for) or recursively (where a function calls itself using a subset of the data). In your example, you can envision a function calling itself and each time it is called it does the following:
calculates the square of j and
adds it to the value returned from calling itself with j decremented
by 1 until
j < i, at which point it returns 0
Once the limiting condition (Point 3) is reached, a bunch of additions that were queued up along the way are triggered.
Learn to Speak The Language before using Idioms
I may get down-voted for this, but you will encounter a lot of advice displaying pythonic idioms for standard solutions. The idiomatic solution for your example would be as follows:
def adder(i,j,k):
return sum(x**k for x in range(i,j+1)) if i<=j else 0
But for a beginner this obscures a lot of the "science". It is far more rewarding to tread the simpler path as a beginner. Once you develop your own basic understanding of devising and implementing algorithms in python, then the idioms will make sense.
Just so you can lean into the above idiom, here's an explanation of what it does:
It calls the standard library function called sum which can operate over a list as well as an iterator. We feed it as argument a generator expression which does the job of the iterator by "drip feeding" the sum function with x^k values as it iterates over the range (1, j+1). In cases when N (which is j-i) is arbitrarily large, using a standard list can result in huge memory overhead and performance disadvantages. Using a generator expression allows us to avoid these issues, as iterators (which is what generator expressions create) will overwrite the same piece of memory with the new value and only generate the next value when needed.
Of course it only does all this if i <= j else it will return 0.
Lastly, make mistakes and ask questions. The community is great and very helpful
Well, do not use print. It is easy to modify your function like this,
if i<=j:
s = 0
for x in range (i, j+1):
s += x**k
return s # print(s) if you really want to
else:
return 0
Usually functions do not print anything. Instead they return values for their caller to either print or further process. For example, someone may want to find the value of Adder(3, 6, 2)+1, but if you return nothing, they have no way to do this, since the result is not passed to the program. A side note, do not capitalize functions. Those are for classes.

Square waves in sympy

I have a problem in sympy with outputing mathematical functions with different calculations for different cases. For example I want to make a function like a saw wave.(1 if -1 < x <1 else 0)
I would like to define a function in a
f = x**2 + 1
like way to make a function that acts like
f = 1 if -1 < x < 1 else 0
Found a page you might be interested in http://docs.sympy.org/dev/modules/sets.html but you don't specify your problem particularly well. If you could provide some code, what you have tried, stuff like that would make it easier for us to help.

How do I insert variable step into Numpy mgrid?

I am trying to use numpy.mgrid to create two grid arrays, but I want a way to insert a variable as the number of steps.
Without a variable number of steps, numpy.mgrid works as expected with this code:
x, y = np.mgrid[0:1:3j, 0:2:5j]
But, what I want is something like this, because I am not able to explicitly state my step number in the line of code to generate the grid arrays (the values may change due to other processes in my script):
num_x_steps = 3
num_y_steps = 5
x, y = np.mgrid[0:1:(num_x_steps)j, 0:2:(num_y_steps)j] #Try convert to complex
Is there a way to do that, that returns a result equivalent to the first method?
I tried running my 3-line code with and without parentheses and tried a couple other modifications, but nothing seemed to work.
NOTE: I tried reading this topic, but I am not sure if what that topic deals with is applicable to this problem; I don't quite understand what is being asked or how it was answered. (Also, I tried running the line of code from the answer, and it returned a MemoryError.) If said topic does answer my problem, could someone please explain it better, and how it applies to my problem?
The glitch is that j following parentheses doesn't convert to a complex number.
In [41]:(1)j
File "<ipython-input-41-874f75f848c4>", line 1
(1)j
^
SyntaxError: invalid syntax
Multiplying a value by 1j will work, and these lines give x, y equivalent to your first line:
num_x_steps = 3
num_y_steps = 5
x, y = np.mgrid[0:1:(num_x_steps * 1j), 0:2:(num_y_steps * 1j)]
I think what you are looking for is to convert the num of steps to a complex number.
num_x_steps = 3
x_steps = complex(str(num_x_steps) + "j")
num_y_steps = 5
y_steps = complex(str(num_y_steps) + "j")
x, y = np.mgrid[0:1:x_steps, 0:2:y_steps]

Filtering out conditioned arrays from a matrix

In Sweden there is a football (soccer) betting game where you try to find the outcome of 13 matches. Since each match can have a home win, a draw or an away team win this leads to 3**13=1594323 possible outcomes. You win if you have 10 to 13 matches correct. You don't want this to occur when a lot of other people also have high scores since the prize sum is divided among all winners. This is the background to the more generic question that I'm looking for an answer to: how to find all arrays that differ by at least x elements from a given array within the matrix (in this case 1594323*13).
The first obvious idea that came to my mind was to have 13 nested for loops and compare one array at the time. However, I'm using this problem as a training session to learn myself Python programming. Python is not the optimal tool for this kind of task and I could turn to C to get a faster program but I'm interested in the best algorithm as such.
In Python I tried the nested for loop method up to 10 matches, then the execution time got too long, 5 seconds on the netbook I'm using. For each added match, the execution time went up tenfold.
Another approach would be to use a database and that might be the solution but I'm curious what the fastest way of solving this kind of problem is. I haven't been successful googling this problem, maybe because it's hard to use the correct description of the problem in a short search.
Here's a recursive solution that terminates in about 5 seconds on my machine, when given an x value of 0 (the worst case). For x values of 10 and above it's nearly instantaneous.
def arrays_with_differences(arr, x):
if x > len(arr):
return []
if len(arr) == 0:
return [[]]
smallColl1 = arrays_with_differences(arr[:len(arr)-1], x)
smallColl2 = arrays_with_differences(arr[:len(arr)-1], x-1)
last = arr[len(arr)-1]
altLast1 = (last + 1) % 3
altLast2 = (last + 2) % 3
result = [smallArr + [last] for smallArr in smallColl1]
result.extend([smallArr + [altLast1] for smallArr in smallColl2])
result.extend([smallArr + [altLast2] for smallArr in smallColl2])
return result
result = arrays_with_differences([1,0,1,0,1,1,1,1,1,1,1,1,1], 4)
print(len(result))

Categories