I have:
A = Path('/a/b/.../m/n/.../z.txt')
B = Path('n/.../z.txt')
I want:
C = Path('/a/b/.../m')
We have well defined, reliable functions for two of the three relationships between these paths:
B == A.relative_to(C)
A == C / B
C == A.unknown_operator(B)
Is there a clean, exact way to compute C given A and B? Or: What's the third, missing operation? Or must I resort to string manipulation?
What about path as string manipulation using str.removesuffix (since py3.9)
A = Path('/a/b/.../m/n/.../z.txt')
B = Path('n/.../z.txt')
C = Path(A.as_posix().removesuffix(B.as_posix()))
print(C) # /a/b/.../m
Or remove part from the end of A until A == C/B
C = Path(A.as_posix())
while C != Path("/") and not B == A.relative_to(C):
C = C.parent
You can use parents field of pathlib.Path:
C = (A.parents[len(B.parents)-1]
if 1 <= len(B.parents) <= len(A.parents) else None)
if C is None or A != C.joinpath(B):
# B is not a suffix of A, proceed accordingly
Related
I'm trying to implement the multivariate chain rule using python, when I try to substitute one of the elements using the built-in sympy function expr.subs() I won't get an answer.
The exercise goes as follows:
Compute df/dx of the following function using the chain rule:
a = x^2
b = exp(a)
c = a + b
d = log(c)
e = sin(c)
f = d + e
And this is the code:
a, b, c, d, e, f = sym.symbols('a b c d e f')
f = d + e
dfd = sym.diff(f, d)
dfe = sym.diff(f, e)
df = sym.Matrix([[dfd, dfe]])
d = sym.log(c)
e = sym.sin(c)
ddc = sym.diff(d)
dde = sym.diff(e)
dd = sym.Matrix([[ddc],[dde]])
dfdd = df#dd
c = a + b
dca = sym.diff(c, a)
dcb = sym.diff(c, b)
dc = sym. Matrix([[dca, dcb]])
dfdc = dfdd#dc
a = x**2
b = sym.exp(a)
result = dfdc.subs(c, (a + b))
result
The result the function .subs() doesn't substitute anything and I don't know why, I tried substituting it using other ways to write the function, like:
dfdc.subs({c : (a + b)})
dfdc.subs(c, a + b)
And even tried to just substitute it for an integer to see it that would work and neither does it.
What am I doing wrong?
The c in your dfdc expression was created before you set c=a+b. So it still appears as c in dfdc. However, by the time you want to do your subs, the c symbol is declared as c=a+b, and so your substitute really reads
dfdc.subs(a+b, a+b)
And that does nothing.
In order to really use c there, do
dfdc.subs(sym.Symbol('c'), a+b)
Is it possible to assign < to a variable, let's say b ?
For example:
b = < .
Edit:
My plan is the following:
a < b < c < d .
I want add the "compares" to a permutation. I know that I can add a b c d to a permutation but I have to change the < too. Please believe me that this is important for my plan. I have to find all possibilities.
You can do it like so
b = '<'
c = '+'
When you want to use it, you have to use the eval function.
eval('5' + b + '10') # '5<10'
>>> True
eval('5' + c + '10') # '5+10'
>>> 15
I wanted to write a function that mirrors a string without using any built in functions and only using a loop.
For example, wordMirror("stackexchange") returns 'stackexchangeegnahcxekcats'.
I wrote the following code using some hints from my previous questions:
def wordMirror(word):
c = ""
for x in word:
c = c + x
return word + c
But it didn't work. I then started to play around with it and just reversed c = c + x to c = x + c and it magically worked.
What exactly is the code reading when I switched the variables?
There is nothing magic about it, the order in which your are adding characters to c is reversed because you are inserting x before what was previously in c.
You should really step through a run by hand:
iteration | x | c
-------------------------------
0 '' ''
1 s s
2 t ts
3 a ats
4 c cats
5 k kcats
6 e ekcats
7 x xekcats
8 c cxekcats
9 h hcxekcats
10 a ahcxekcats
11 n nahcxekcats
12 g gnahcxekcats
13 e egnahcxekcats
From this simple table you should be able to see how the string is growing. Learning how to execute your programs by hand is a vital skill to have.
Walking through code one step at a time helps us make sense of it.
c = c + x
In this case, say c = "stackexchange". You'll go through the letters one by one, with each one going into x.
# x = "s"
c = c + x # c = "" + "s" = "s"
# x = "t"
c = c + x # c = "s" + "t" = "st"
# x = "a"
c = c + x # c = "st" + "a" = "sta"
Now let's try it the other way.
# x = "s"
c = x + c # c = "s" + "" = "s"
# x = "t"
c = x + c # c = "t" + "s" = "ts"
# x = "a"
c = x + c # c = "a" + "ts" = "ats"
That hopefully makes it clear why the order of addition gets you the results you do. When you're trying to figure out why code works the way it does, stepping through it slowly often will show you what's happening more clearly. You can do this by 1) finding a good IDE, or 2) adding print statements in strategic locations. Try adding a print x, c line immediately after c = x + c and you'll watch it get built one letter at a time.
I know you're looking for loops, but why not just:
c = "hello"
output = c + c[::-1]
print output
#=> 'helloolleh'
This takes your string c, which you can think of as an array of characters, and steps through it in reverse ( the -1 in the last argument to slicing notation does this). That way it allows you to easily concatenate your starting string and its mirrored version.
Many python developers believe that simple is better than complex. This sort of trick is a way to increase the ease at which you and other developers can understand and maintain the code you produce.
This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 9 years ago.
2 questions...
1) I am trying to wrap my brain around this...
I am to understand that variables can take values using such code syntax as this:
a ,b = 2, 3
and that this would be the same as coding:
a = 2
b = 3
I hope this is correct.
So here is my puzzlement. I have the following code using a generator:
def fibonacci_generator() :
a = b = 1
while True :
yield a
a , b = b , a + b
fib = fibonacci_generator()
for i in fib :
if i > 100 :
break
else :
print ('Generated: ', i)
print (next(fib))
(yes this is code from a python learning book)
If I were to rewrite this code and instead assign my a and b variables like so:
yield a
a = b
b = a + b
then I get different returns for a.
I am not understanding why this is??? Super frustrated about it!
2) When I run the code as written the first time above, I get the number 233 printed at the end. I also cannot figure out why??!!
In this code:
a, b = b, a + b
a is set to b, and b is set to a+b.
In this code:
a = b
b = a + b
a is set to b, and b is afterwards set to a+b. But since a is already set to b, then b is in fact set to b+b.
a , b = b , a + b
is not the same as
a = b
b = a + b
Because, when you say
a, b = b, a + b
It will first prepare the values on the right side b, a + b and assign them to the variables on the left.
Python computes the right hand side first and then assigns the value (or unpacks it) on the left hand side. So, in the example:
a, b = b, a+b
compared to:
a = b
b = a + b
You have different values for a when you go to compute a + b. In the second example, when you compute a + b it is equivalent to computing b + b!
You are probably missing the flow of data.
a = b ...eqI
b = a+b ...eqII
here, before executing b eqII, a has already stored bas a value of itself. Now when yow try execute b of eqII it comes like b=b+b. Because after executing eqI when it comes to eqII, a is bnow.
But in python you can avoid this conflict if you try a, b = b, a+b.
For your second question:
I am not sure about your code but this one will work fine in the sense of your code...
a = b = 1
while True :
a , b = b , a + b
if a and b > 100:
break
else: print a, b
try it !!
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. Because that you get different results
a, b = b, a+b
This line computes b and a+b before performing any assignment. Strictly speaking, it computes a tuple (b, a+b) and then unpacks the elements of the tuple to assign them to a and b.
a = b
b = a+b
This assigns a, then computes a+b using the new value of a.
Assume you are given a large number of variables that need to be initialized to None. A naive way to do this would be to count the number of variables on the left, and create a list of the same size on the right:
a, b, c, d, e, f, g, h, i, j = [None]*10
Is there a way to do this without having to count the variables? If one uses this pattern often, it could become tedious to have to count the number of variables.
a = b = c = d = e = f = g = h = i = j = None
Note: don't use this for mutable types. If you're curious why, this demonstrates:
>>> a = b = []
>>> a.append(1)
>>> a
[1]
>>> b
[1]
Is there a reason you're not doing this?
a = b = c = d = e = f = g = h = i = j = None
I'm not too familiar with the intricacies of Python's syntax so please correct me if I'm wrong.