Extract first N position of floating number - python

I have a list of floating point value, and I'd like to plot it onto a graph. How can we extract the first 4 precision from a floating number, before putting into another new list?
C = []
C.append(23.1234567890)
C.append(14.1234567890)
print ('C - ' + str(C))
D = []
D.append(C[0])
D.append(C[1])
print ('D - ' + str(D))
Got
C - [23.123456789, 14.123456789]
D - [23.123456789, 14.123456789]
Expecting
C - [23.123456789, 14.123456789]
D - [23.1235, 14.1235]

You can get a string representation pretty easily:
>>> '{:.4f}'.format(23.1234567890)
'23.1235'
You can also use the round function:
>>> round(23.1234567890, 4)
23.1235
Note that if you use round, the number will almost never be exactly to the 4 digits of precision that you want due to the representation of floating point numbers.

You can do it, for example, through string manipulation:
strC = split(str(C), ".")
strC = strC[0] + "." + strC[1][:5]
print ('C - ' + strC)

You can do it using string formatting:
C = []
C.append(23.1234567890)
C.append(14.1234567890)
print ('C - ' + str(C))
D = []
D.append(float("%.4f" % C[0]))
D.append(float("%.4f" % C[1]))
print ('D - ' + str(D))

You can mathematically remove the unneeded digits, using the modulo % function:
C = []
C.append(23.1234567890)
C.append(14.1234567890)
print ('C - ' + str(C))
D = []
for i in C:
D.append(i - (i% (10**-4)))
print ('D - ' + str(D))
Where -4 is the number of digits you want to keep. 10**-4 is 0.0001.

Related

Regex Retrieve all text before string until space

I am trying to parse the coefficient of "a" in a quadratic equation (ax^2 + bx + c).
However, the length of the coefficient can vary.
For instance, here are some of the intended outcomes:
input: 5x^2 + 3x + 4
output: 5
input: 12x^2 + 2x - 6
output: 12
The number could also be in the middle of the equation.
input: 2x - 3x^2 + 4
output: 3
How would I get the whole text before "x^2" until their is a white space?
I have tried using the split() function:
a = equation.split("x^2")
a = a[0]
but this would not work in the third example
Here you are
[-+]?\d+(\.\d+)?(?=x\^)
Test it here
Be aware that this regex will only match simple cases, for example, it will not match 2E3.
Tip: use RegEx 101 to test your pattern:
pattern = re.compile(r'([\+\-\d.]*)x\^2')
tests = [
'5x^2 + 3x + 4',
'12x^2 + 2x - 6',
'2x - 3x^2 + 4',
'x^2 - 2x + 1',
'-x^2 + 6x - 9'
]
for t in tests:
m = pattern.search(t)
text = m.group(1)
if text == '':
coeff = 1
elif text == '-':
coeff = -1
else:
coeff = float(text)
print(coeff)
Prints:
5.0
12.0
3.0
1
-1
I saw that using split is an option too from the question. So you want to get the whole text before the numbers with the ^ operator.
This will only work for these three examples:
x = '5x^2 + 3x + 4'
y = '12x^2 + 2x - 6'
z = '2x - 3x^2 + 4'
print(x.split()[0])
print(y.split()[0])
print(z.split('+')[0])
# split default argument is space
Output
5x^2
12x^2
2x - 3x^2
And If you want to take only the numbers with the ^ operator without the whole text before, change z.split('+')[0] to:
print(z.split()[2])
# 3x^2

SymPy - Treating numbers as symbols

How can I treat numbers as symbols in SymPy?
For example, if I am performing a factorization with symbols I get:
from sympy import factor
factor('a*c*d + a*c*e + a*c*f + b*c*d + b*c*e + b*c*f')
c*(a + b)*(d + e + f)
I would like the same behaviour when I am using numbers in the expression.
Instead of
from sympy import factor
factor('2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f')
4013*c*(d + e + f)
I would like to get
from sympy import factor
factor('2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f')
c*(2006 + 2007)*(d + e + f)
Replace each constant with a unique symbol.
Factor the resulting expression.
Replace the unique symbols with the constants.
For your given case, something like this:
simple = factor('const2006*c*d + const2006*c*e + const2006*c*f + const2007*c*d + const2007*c*e + const2007*c*f')
simple.replace("const", '')
print(simple)
This should give you the desired output. You can identify numeric tokens in the expression with a straightforward regex or trivial parser -- either of which is covered in many other locations.
Symbol trickery to the rescue: replace your numbers with Symbols having a name given by the number. In your case you don't have to watch for negative versions so the following is straightforward:
>>> s = '2006*c*d + 2006*c*e + 2006*c*f + 2007*c*d + 2007*c*e + 2007*c*f'
>>> eq = S(s, evaluate=False); eq
2006*c*d + 2007*c*d + 2006*c*e + 2007*c*e + 2006*c*f + 2007*c*f
>>> reps = dict([(i,Symbol(str(i))) for i in _.atoms(Integer)]); reps
{2006: 2006, 2007: 2007}
>>> factor(eq.subs(reps))
c*(2006 + 2007)*(d + e + f)
Note: the evaluate=False is used to keep the like-terms from combining to give 4013*c*d + 4013*c*e + 4013*c*f.

Addition of two binaries numbers in Python

Hey guys i have a trouble when i want to add two binaries numbers in Python, i mean i can enter a chain of character in a form of a string but i don't know how to select a specific value in the chain. Here is my code:
chaina = input('Enter your first binary number')
chainb = input('Enter your second binary number')
liste = str()
r = 0
for i in range [-1,chaina]:
t = 0
t = chaina() + chainb() + r
if t == 2 :
r = 1
liste = str(t) + liste
elif t == 0 or t == 1:
r = 0
liste = str(t) + liste
To add two binary numbers chaina and chainb:
bin(eval('0b{} + 0b{}'.format(chaina, chainb)))
Or, if you want the binary number without the leading '0b':
format(eval('0b{} + 0b{}'.format(chaina, chainb)), 'b')
Explanation
Assume for illustration that chaina = '1010' and chainb = '1111'. Then:
>>> '0b{} + 0b{}'.format(chaina, chainb)
'0b1010 + 0b1111'
By applying eval() on this string, we get the same result as if we typed the expression 0b1010 + 0b1111 directly into Python console.
>>> 0b1010 + 0b1111
25
>>> eval('0b1010 + 0b1111')
25
Finally, bin() produces a binary representation of the number passed to it as an argument:
>>> bin(25)
'0b11001'
The same thing is accomplished by calling format() with a 'b' argument:
>>> format(25, 'b')
'11001'
All put together, we are getting the expressions shown above.
Why don't you simply convert them into decimal and add them as you would do with decimals:
y = '0b101010'
z = '0b101010'
print(int(y,2) + int(z,2))
print(bin((int(y,2) + int(z,2))))
Assuming that you want to do a binary sum by hand, you must:
process both numbers starting from the end (reversed will help here)
consistently add bits processing carry until the lengther of both numbers is exhausted
reorder the result bits (here again reversed)
Code could be (assuming that you can be sure that chaina and chainb only consist in 0 and 1 characters, no test for it here):
def binsum(chaina, chainb):
def next0(it):
"""Retrieve next digit from a binary representation, 0 when exhausted"""
try:
return int(next(it))
except StopIteration:
return 0
a = reversed(chaina) # reverse chains to start with lowest order bit
b = reversed(chainb)
r = 0
result = [] # future result
for i in range(n):
t = next0(a) + next0(b) + r # add with carry
if t > 1:
t -= 2
r = 1
else:
r = 0
result.append('1' if t else '0')
if r != 0: # do not forget last carry
result.append('1')
return ''.join(result)
A couple of suggestions
normalize the lengths of the bit strings
l0, l1 = map(len, (str0, str1))
if l0 < l1:
str0 = "0"*(l1-l0) + str0
elif l1 < l0:
str1 = "0"*(l0-l1) + str1
do a loop on the reversed strings elements and construct the binary string bottom up
remainder = 0
result = ""
for bit_0, bit1 in zip(reversed(str0), reversed(str1)):
bit_0, bit_1 = map(int, (bit_0, bit_1))
new_bit, remainder = f(bit_0, bit_1, remainder)
result = str(new_bit) + result
if remainder != 0
...
writing f(bit_0, bit_1, remainder) and treating what to do if remainder is not null at the end of the loop is left as an exercise.

Returning original string with symbols between each character

I'm trying to make my program return the exact same string but with ** between each character. Here's my code.
def separate(st):
total = " "
n = len(st + st[-1])
for i in range(n):
total = str(total) + str(i) + str("**")
return total
x = separate("12abc3")
print(x)
This should return:
1**2**a**b**c**3**
However, I'm getting 0**1**2**3**4**5**6**.
You can join the characters in the string together with "**" as the separator (this works because strings are basically lists in Python). To get the additional "**" at the end, just concatenate.
Here's an example:
def separate(st):
return "**".join(st) + "**"
Sample:
x = separate("12abc3")
print(x) # "1**2**a**b**c**3**"
A note on your posted code:
The reason you get the output you do is because you loop using for i in range(n): so the iteration variable i will be each index in st. Then when you call str(total) + str(i) + str("**"), you cast i to a string, and i was just each index (from 0 to n-1) in st.
To fix that you could iterate over the characters in st directly, like this:
for c in st:
or use the index i to get the character at each position in st, like this:
for i in range(len(st)):
total = total + st[i] + "**"
welcome to StackOverflow!
I will explain part of your code line by line.
for i in range(n) since you are only providing 1 parameter (which is for the stopping point), this will loop starting from n = 0, 1, 2, ... , n-1
total = str(total) + str(i) + str("**") this add i (which is the current number of iteration - 1) and ** to the current total string. Hence, which it is adding those numbers sequentially to the result.
What you should do instead is total = str(total) + st[i] + str("**") so that it will add each character of st one by one
In addition, you could initialize n as n = len(st)

Leading/prefix 0s in out of for loop

I am writing a four loop in my program that writes data to a file. I'm wanting for the output to be formatted as follows
frame001 + K.1
frame002 + K.2
...
frame099 + K.99
frame100 + K.100
So far I am doing
for f in range(1, 100):
file.write('frame' + str(f) + ' + K.' + str(f) + '\n')
I have no problem having the K part come out correctly as K.1-K.100, but I don't know how to have prefix zeros/have it output also frame00F to frameFFF with the appropriate amount of preceding zeros.
Using str.format:
>>> 'frame{0:03d} + K.{0}\n'.format(1)
'frame001 + K.1\n'
>>> 'frame{0:03d} + K.{0}\n'.format(100)
'frame100 + K.100\n'
BTW, range(1, 100) will not yield 100. If you want 100 to be included, that should be range(1, 101).
If you are using old version of Python (Python 2.5-), use % operator (String formatting operator) instead (need to specify multiple argument unlike str.format)
>>> 'frame%03d + K.%d\n' % (1, 1)
'frame001 + K.1\n'
>>> 'frame%03d + K.%d\n' % (100, 100)
'frame100 + K.100\n'
If you don't want to repeat arguments, you can pass mapping instead with slightly different format specifier:
>>> 'frame%(i)03d + K.%(i)d\n' % {'i': 1}
'frame001 + K.1\n'

Categories