Modify function to use list comprehision in Python - python

I have got a function:
def euler9():
for b in range(1, 500):
a = (500000 - 1000 * b) / (1000 - b)
if a % 1 == 0:
print(b * a * (1000 - a - b))
And I want to make it in one line like
x*x for x in range(1,1)
This is what I have done:
def euler9():
print([b * a * (1000 - a - b) for b in range(1, 500) for a in (500000 - 1000 * b) / (1000 - b) if a % 1 == 0])
but I do not know what am I doing wrong. I have got an error:
TypeError: 'float' object is not iterable

for is for iteration (looping). When you say for b in range(1, 500) you are not setting b = range(1, 500), since that would make b a list. You are extracting each individual value and using them one at a time. You cannot extract values from a float.
Python has no syntax for simple assignment in list comprehensions, but you can work around that by putting the value inside a single-element list, thus making it iterable:
[b * a * (1000 - a - b) for b in range(1, 500) for a in [(500000 - 1000 * b) / (1000 - b)] if a % 1 == 0]
(You can put print(...) around the initial expression if you want but I assume you want to actually use the values)
But don't ever do this, it's hard to read and unnecessary.

Here for a in (500000 - 1000 * b) / (1000 - b) you are trying to iterate over a float number which is the result of a devision.
As a quick fix try this:
def euler9():
print([b * ((500000 - 1000 * b) / (1000 - b)) * (1000 - ((500000 - 1000 * b) / (1000 - b)) - b)
for b in range(1, 500) if ((500000 - 1000 * b) / (1000 - b)) % 1 == 0])
But, as you see it gets a bit messy that way, and it is recommended to use loops instead of list comprehension when things get complicated.

Turn it into a generator by changing print to yield:
def euler9():
for b in range(1, 500):
a = (500000 - 1000 * b) / (1000 - b)
if a % 1 == 0:
yield (b * a * (1000 - a - b))
Then you can access it as a list comprehension:
print [x for x in euler9()]

Related

What does .sum( ) do specifically in this situation?

Usually when I've seen the sum function used, it has taken an argument within it's parentheses. What exactly does it do in the following, and what is the point of it?
a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b)
print(b.grad_fn)

Python - multiple iterations over lists of different size

Does anyone could help with this code? I'm writing this code to compute some values over some equations. I satarted by reading the CSV values into a dictionary, but after calculating the values to reach the final set of parameters, I cannot find a way to iterate repeatedly over the same list.
To simply, I have two input lists dPdT and listT. I need to iterate every parameter of list dPdT over listT and produce three different lists P.
I thank anyone willing to help. This is a study project for a course.
# Request user's interval parameters for calculations
print("Inform the temperature range and interval (°C). Only integers.")
minT = int(input("Min: "))
maxT = int(input("Max: "))
stepT = int(input("Temperature interval: "))
# create a list of temperature values to compute pressure parameters
listT = []
for x in range(minT, (maxT+stepT), stepT):
listT.append(x)
# Open CSV file in read mode to acces data and read it into a dictionary
with open(CSVfile, "r") as CSV:
reader = csv.DictReader(CSV)
listDict = []
# Creates a list of dictionaries with the fluid inclusion parameters
for lines in reader:
listDict.append(lines)
# Define list parameters to be computated
a, b, c, dPdT, P = [], [], [], [], []
# Loop iterates over the dictionary list and computates parameters a,b,c stored in lists a,b,c
for i, rows in enumerate(listDict):
a.append(i)
b.append(i)
c.append(i)
if "sal" in rows:
a[i] = (18.28 + 1.4413 * float(rows["sal"]) + 0.0047241 * float(rows["sal"]) ** 2
+ 0.0024213 * float(rows["sal"]) ** 3 + 0.000038064 * float(rows["sal"]) ** 4)
b[i] = (0.019041 - 1.4268 * 0.01 * float(rows["sal"]) + 5.66012 * 0.0001 * float(rows["sal"]) ** 2
- 4.2329 * 0.000001 * float(rows["sal"]) ** 3 - 3.0354 * 0.00000001 * float(rows["sal"]) ** 4)
c[i] = (- 1.5988 * 0.0001 + 3.6892 * (10 ** -5) * float(rows["sal"]) - 1.9473 * (10 ** -6) * float(rows["sal"]) ** 2
+ 4.1674 * (10 ** -8) * float(rows["sal"]) ** 3 - 3.3008 * (10 ** -10) * float(rows["sal"]) ** 4)
# Loop iterates over the dictionary list and computates dPdT to store the values in list dPdT
for i, rows in enumerate(listDict):
dPdT.append(i)
if "th" in rows:
dPdT[i] = a[i] + b[i] * float(rows["th"]) + c[i] * float(rows["th"]) ** 2
# Loop populates list P (pressure values)
for i in range(len(listT)):
P.append(i)
# problem starts here: I need to iterate over the listT or P, repeating it for every dPdT values.
# Loop to calculate P based on lits dPdT and listT.
while i in range(len(dPdT)):
for j in range(len(P)):
P[j] = dPdT[j] * listT[j]
I need to iterate every parameter of list dPdT over listT and produce three different lists P.
I'm sorry it's hard to understand your question. Explain this line.
Do you want to multiply each element in dPdT with each element in listT resulting in a P array of length = len(dPdT) * len(listT) ??? Because your current code is doing exactly that.
Edit:
Ok, I understand. I think the best way to go about it is to make P a 2d array. Basically, P will be a huge array containing multiple arrays within it. len(P) = len(dPdT) and len(P[i]) = len(listT)
P = [ [0 for i in range(len(listT)] for j in range(len(dPdT)) ]
for row in range(len(dPdT)):
for col in range(len(listT)):
P[row][col] = dPdT[row] * listT[col]
I hope this is what you wanted. Basically, the nth element of P will also be array containing the numbers in listT all multiplied by the nth element of dPdT.
:)

Pretty print a factorized polynomial

from math import sqrt
def factor(a, b, c):
x1 = (-1 * b) + sqrt(b * b - (4 * a * c))
x2 = (-1 * b) - sqrt(b * b - (4 * a * c))
solution1 = (x1 / (2 * a))
solution2 = (x2 / (2 * a))
expression1 = ['x', (-1 * solution1)]
expression2 = ['x', (-1 * solution2)]
return expression1, expression2
print(factor(1, -17, 12))
I cannot figure out how to replace the values in the list to make the output look cleaner. I have tried arranging the values in different orders and adding strs to make it look better, but to no avail.
How can I make the output look like (x - 16.2)(x - 0.73) instead of (['x', -16.262087348130013], ['x', -0.7379126518699879])? I have not been successful in removing the unnecessary characters from the output.
I just want to remove the bracets and quotes.
Here's a painfully spread out (and ugly) solution, but one which should be useful as you learn the formatting and other tricks required to get this exactly as you want:
def pretty_product(e1, e2):
a = e1[0]
op1 = '+' if e1[1] >= 0 else '-'
b = e1[1]
c = e2[0]
op2 = '+' if e2[1] >= 0 else '-'
d = e2[1]
return f'({a} {op1} {abs(b):.2f})({c} {op2} {abs(d):.2f})'
print(pretty_product(['x', 2567.235235], ['y', -423.12313124214]))
Result is:
(x + 2567.24)(y - 423.12)
Note: if you want to suppress a possible + 0.00 you have more code to write, but it should be easy to add, I think. :)
You can use f-string
your_tuple = (solution1, solution2)
print(f'(x - {your_tuple[0]})(x - {your_tuple[1]})')

When I convert an expression using shortcut operators the output is wrong

I read that if I have the following expression:
variable = variable op expression
It can be simplified and shown as follows:
variable op= expression
For example: i = i + 2 * j --> i += 2 * j
However, I have used the previous example in a = a / 2 * b --> a /= 2 * b
Let a=6 and b=3. Using both values in a=a/2*b, the output is 9. However, in the case of a /= 2* b, the output is 1
This is because you are changing the order of operations.
a = a / 2 * b is interpreted as "Divide a by 2, then multiply by b, then store the result in a", or a = (a / 2) * b.
a /= 2 * b is interpreted as "Multiply 2 by b, then divide a by the result, and store the final result in a", or a = a / (2 * b).
I hope this helps.

Comparing two numbers without loops or branching in Python

I have to compare two numbers and write greater, then smaller, but I don't know how to get smaller one. I currently have this code:
a = int(input())
b = int(input())
c = round(((a + b) + abs(a - b)) / 2)
x = "should be smaller one"
print("{0}\n{1}".format(c, x))
smaller is : c = round(((a + b) - abs(a - b)) / 2)
If I right understand you:
In [1]: a , b = 3, 4
In [2]: smaller = a if a < b else b
In [3]: smaller
Out[3]: 3
Here you can replace < to other operator

Categories

Resources