How to round numbers in place in a string in python - python

I'd like to take some numbers that are in a string in python, round them to 2 decimal spots in place and return them. So for example if there is:
"The values in this string are 245.783634 and the other value is: 25.21694"
I'd like to have the string read:
"The values in this string are 245.78 and the other value is: 25.22"

What you'd have to do is find the numbers, round them, then replace them. You can use regular expressions to find them, and if we use re.sub(), it can take a function as its "replacement" argument, which can do the rounding:
import re
s = "The values in this string are 245.783634 and the other value is: 25.21694"
n = 2
result = re.sub(r'\d+\.\d+', lambda m: format(float(m.group(0)), f'.{n}f'), s)
Output:
The values in this string are 245.78 and the other value is: 25.22
Here I'm using the most basic regex and rounding code I could think of. You can vary it to fit your needs, for example check if the numbers have a sign (regex: [-+]?) and/or use something like the decimal module for handling large numbers better.

Another alternative using regex for what it is worth:
import re
def rounder(string, decimal_points):
fmt = f".{decimal_points}f"
return re.sub(r'\d+\.\d+', lambda x: f"{float(x.group()):{fmt}}", string)
text = "The values in this string are 245.783634 and the other value is: 25.21694"
print(rounder(text, 2))
Output:
The values in this string are 245.78 and the other value is: 25.22

I'm not sure quite what you are trying to do. "Round them in place and return them" -- do you need the values saved as variables that you will use later? If so, you might look into using a regular expression (as noted above) to extract the numbers from your string and assign them to variables.
But if you just want to be able to format numbers on-the-fly, have you looked at f-strings? f-string
print(f"The values in this string are {245.783634:.2f} and the other value is: {25.21694:.2f}.")
output:
The values in this string are 245.78 and the other value is: 25.22.

You can use format strings simply
link=f'{23.02313:.2f}'
print(link)
This is one hacky way but many other solutions do exist. I did that in one of my recent projects.

Related

Problems with function isin, problem with number, with words working normaly

I have a problem with function:
print(df.loc[df['Kriterij1'] == '63'])
and i was tried with (the same)
df[df.Kriterij1.isin(['aaa','63'])]
When I want to try filtered by numbers the output is only the head (empty cells) its work only for word 'aaa'.
Or maybe i can use anoter function?
I think you need change '63' (string) to 63 (number), if mixed numeric with strings values:
print(df.loc[df['Kriterij1'] == 63])
print(df[df.Kriterij1.isin(['aaa',63])])

How can I replace a character with a number in a string?

How do I place a variable in .replace() in python. For example:
x = 2
example = example2.replace("1", x)
I think its clear what I am looking for, I just have no clue how to do it.
My comments are based on Python v2.7:
In your code, "x" is assigned a integer value, they do not have replace method.
Instead, if "x" had carried normal string, then replace is available and this is how it works:
var2 = "palindrome syndrome"
print var2.replace("drome", "pal", 2)
Output:
palinpal synpal
In the statement, var2.replace, there are three arguments:
"drome" is the substring to find and replace with new string "pal" and do this for two occurrences of "drome".

complement/negate a boolean string in python

I have a list of boolean strings. Each string is of length 6. I need to get the complement of each string. E.g, if the string is "111111", then "000000" is expected. My idea is
bin(~int(s,2))[-6:]
convert it to integer and negate it by treating it as a binary number
convert it back to a binary string and use the last 6 characters.
I think it is correct but it is not readable. And it only works for strings of length less than 30. Is there a better and general way to complement a boolean string?
I googled a 3rd party package "bitstring". However, it is too much for my code.
Well, you basically have a string in which you want to change all the 1s to 0s and vice versa. I think I would forget about the Boolean meaning of the strings and just use maketrans to make a translation table:
from string import maketrans
complement_tt = maketrans('01', '10')
s = '001001'
s = s.translate(complement_tt) # It's now '110110'
Replace in three steps:
>>> s = "111111"
>>> s.replace("1", "x").replace("0", "1").replace("x", "0")
'000000'

Slicing a string in Python

When we need to slice a string at a particular location, we need to know the index from where we want to.
For example, in the string:
>>> s = 'Your ID number is: 41233'
I want to slice the string starting from : and get the number.
Sure I can count at what index : is and then slice, but is that really a good approach?
Of course I can do a s.index(':'). But that would be an extra step, so I came up with something like:
>>> print s[(s.index(':')+2):]
41233
But somehow I don't like the looks of it.
So my question is, given a long string which you want to slice, how do you find the index from where to begin the slicing in the easiest and most readable way? If there is a trick to do it orally, I would love to know that.
Perhaps you could use split():
>>> s = 'Your ID number is: 41233'
>>> print s.split(":")[1].strip()
41233
text, sep, number = 'Your ID number is: 41233'.partition(':')
print number
works too. But it won't fail if the separator is not in the string.
That unpacking works for split too:
text, number = 'Your ID number is: 41233'.split(':',1)
Another approach is 'Your ID number is: 41233'.split(':')[1].strip().
So my question is, given a long string which you want to slice, how do you find the index from where to begin the slicing in the easiest and most readable way?
When "where to begin the slicing" is a specific symbol, you don't; instead you just as Python to split the string up with that symbol as a delimiter, or partition it into the bits before/within/after the symbol, as in the other answers. (split can split the string into several pieces if several delimiters are found; partition will always give three pieces even if the symbol is not there at all.)
If there is a trick to do it orally, I would love to know that.
I really don't think you mean "orally". :)
I wouldn't use slicing at all unless there's some other compelling reason you want to do so. Instead, this sounds like a perfect job for re the regular expression module in the standard library. Here's an example of using it to solve your problem:
import re
compile_obj = re.compile(r'Your ID number is:\s(?P<ID>\d+)')
s = 'Your ID number is: 41233'
match_obj = compile_obj.search(s)
if match_obj:
print match_obj.group('ID')
# 41233
Recently came across partition
string = "Your ID number is: 41233"
string = string.partition(':')
print string[2]

Formatting dict.items() for wxPython

I have a text box in wxPython that takes the output of dictionary.items() and displays it to the user as items are added to the dictionary. However, the raw data is very ugly, looking like
[(u'BC',45)
(u'CHM',25)
(u'CPM',30)]
I know dictionary.items() is a list of tuples, but I can't seem to figure out how to make a nice format that is also compatible with the SetValue() method of wxPython.
I've tried iterating through the list and tuples. If I use a print statement, the output is fine. But when I replace the print statement with SetValue(), it only seems to get the last value of each tuple, rather than both items in the tuple.
I've also tried creating a string and passing that string to SetValue() but, again, I can only get one item in the tuple or the other, not both.
Any suggestions?
Edit: Yes, I am passing the results of the dictionary.items() to a text field in a wxPython application. Rather than having the results like above, I'm simply looking for something like:
BC 45
CHM 25
CMP 30
Nothing special, just simply pulling each value from each tuple and making a visual list.
I have tried making a string format and passing that to SetValue() but it gets hung up on the two values in the tuple. It will either double print each string and add the integers together or it simply returns the integer, depending on how I format it.
There is no built-in dictionary method that would return your desired result.
You can, however, achieve your goal by creating a helper function that will format the dictionary, e.g.:
def getNiceDictRepr(aDict):
return '\n'.join('%s %s' % t for t in aDict.iteritems())
This will produce your exact desired output:
>>> myDict = dict([(u'BC',45), (u'CHM',25), (u'CPM',30)])
>>> print getNiceDictRepr(myDict)
BC 45
CHM 25
CPM 30
Then, in your application code, you can use it by passing it to SetValue:
self.textCtrl.SetValue(getNiceDictRepr(myDict))
Maybe the pretty print module will help:
>>> import pprint
>>> pprint.pformat({ "my key": "my value"})
"{'my key': 'my value'}"
>>>
text_for_display = '\n'.join(item + u' ' + unicode(value) for item, value in my_dictionary.items())
use % formatting (known in C as sprintf), e.g:
"%10s - %d" % dict.items()[0]
Number of % conversion specifications in the format string should match tuple length, in the dict.items() case, 2. The result of the string formatting operator is a string, so that using it as an argument to SetValue() is no problem. To translate the whole dict to a string:
'\n'.join(("%10s - %d" % t) for t in dict.items())
The format conversion types are specified in the doc.
That data seems much better displayed as a Table/Grid.
I figured out a "better" way of formatting the output. As usual, I was trying to nuke it out when a more elegant method will do.
for key, value in sorted(self.dict.items()):
self.current_list.WriteText(key + " " + str(self.dict[key]) + "\n")
This way also sorts the dictionary alphabetically, which is a big help when identifying items that have already been selected or used.

Categories