String Mirror Function - python

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.

Related

pathlib get base path, given the absolute and relative paths

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

Assign comparison operator to variable?

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

Plotting with SymPy

With SymPy, I can plot a function with:
f, a = symbols('f a')
f = a + 10
plot(f)
However, if I define the function as:
f, a, b = symbols('f a b')
f = a + b
b = 10
plot(f)
Then I get an error stating:
ValueError: The same variable should be used in all univariate
expressions being plotted.
How can I plot f if I define f = a + b, considering that b is assigned a constant value before plotting the function?
The lines
f, a, b = symbols('f a b')
f = a + b
b = 10
don't change b in the expression. If you print f you'll see that it is still defined as a + b.
You are confusing Python variables with SymPy symbols. In the first line, the Python variable b points to a SymPy symbol named b (in fact, they need not be the same name; you could have also written x = Symbol('b') and y = a + x). In the second line, the variable f points to a SymPy expression containing the symbol b. In the third line, the variable b points to the integer 10. This doesn't not change any previous lines that used the variable b, since they have already been run. It's no different than if you ran
a = 1
b = 1
c = a + b
b = 2
You would expect the value of c at the end to be 2, not 3. Similarly, when b points to a Symbol, expressions you create with it use a Symbol, but if you change it to point to a number, it doesn't affect previous lines from when it was a Symbol.
The recommended way to deal with this in SymPy is to avoid assigning the same variable to a symbol and then later to a non-symbol (it's worth pointing out that your definition of f in the first line is completely useless, since you immediately redefine it in the second line). To replace a symbol in an expression, use subs:
a, b = symbols('a b')
f = a + b
f1 = f.subs(b, 10)
Note that subs does not change the original f. It returns a new expression.
This document may also help clear this confusion up.
If you didn't want to use substitution as in the other answer, you could make f an actual function of course
def f(a, b):
return a + b
a = symbols('a')
b = 10
plot(f(a,b))
You must substitute b into f:
plot(f.subs('b', b))

How to make a "Regular Expression Template" that gets values in between certain places. Python 3

I am inquiring about how to make something similar to a Python Template in reverse, using regular expressions. A template for a quadratic would look something like this:
("${a}x^2+${b}x+${c}")
How can one reverse this to make it instead take a string and pull out a, b, c.
The reason behind this question is I was recently trying to perform the task to get a and b like this:
a = []
for character in self.text:
if re.search("\d", character):
a.append(character)
else:
break
b = re.search('%s(.*)%s' % ("\d*[\w][\^]2[+-]", "\w[+-]"), self.text).group(1)
return a, b
It works fine but it's not very pythonic and it's very cumbersome. I'm sure there's a better way.
Here's a possible start on what I think you're asking for -- it uses regular expressions to tease out the quadratic constants:
import re
EXAMPLES = [
"6x^2",
"5x",
"4",
"x^2 - 3x - 4",
"6x^2 + 11x - 35",
"x^2 - 7x",
"2x^2 + 5x + 3",
"5x - 3",
"x^2 - 3",
]
QUADRATIC_PATTERN = r"(?:(\d*)[a-z]\^2)?" r"(?:\s*[-+]\s*)?" r"(?:(\d*)[a-z])?" r"(?:\s*[-+]\s*)?" r"(\d*)?"
for equation in EXAMPLES:
matchobj = re.search(QUADRATIC_PATTERN, equation)
if (matchobj):
print(equation, ": a =", matchobj.group(1), "b =", matchobj.group(2), "c =", matchobj.group(3))
else:
print("misread equation:", equation)
The QUADRATIC_PATTERN is defined as a series of raw strings that Python will concatenate into one string -- this just made it easier to develop and debug. See re.VERBOSE for a different/better way to do this.
The above produces:
6x^2 : a = 6 b = None c =
5x : a = None b = 5 c =
4 : a = None b = None c = 4
x^2 - 3x - 4 : a = b = 3 c = 4
6x^2 + 11x - 35 : a = 6 b = 11 c = 35
x^2 - 7x : a = b = 7 c =
2x^2 + 5x + 3 : a = 2 b = 5 c = 3
5x - 3 : a = None b = 5 c = 3
x^2 - 3 : a = b = None c = 3
Where None means the term wasn't present and an empty result means the term was present but no constant was given.

python generators/ variable [duplicate]

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.

Categories

Resources