Python binary operators and word splitting - python

I've been working on some homework I've been given and I've ran into a couple problems. I'm hoping someone can shed some light on them and perhaps give me some examples to help aide me.
My first question deals with binary operators in python.
Problem #13: Python supports 18 different binary operators. Experiment with each of these, using arguments that are both integer, both floating point, and both string. Not all operators work with each argument type. Fill in the following table. For each operator, provide either a short description and indicate the type of the result or the words “not legal”.
Operator Integer Floating point String
+
-
*
**
/
%
<<
>>
&
|
^
<
>
<=
>=
==
!=
<>
In this example we're supposed to explain how to operator works as an integer, float point and a string. What confuses me is the float and string aspect, using the addition portion as an example:
Would the integer aspect be something like x=3 y=4 x+y=answer (to show as an integer)? If so how would I go about showing examples of the float and string portion.
My second question deals with string splitting
Problem #20: Each row in the following table consists of a starting word and an ending word. Assign the starting word to the name w. Then using only indexing and slicing commands, convert the starting word into the ending word.
Starting word Ending word Command
w=’kyoto’ ‘tokyo’ w[3:]+w[:3]
w=’bread’ ‘bead’ w[0]+w[2:]
w=’kartasura’ ‘surakarta’ w[5:]+w[:5]
w=’listen’ ‘silent’
As you can see I've completed the first three which seemed relatively simple, I had to rearrange the words. The final one confuses me because I am not longer flipping the back with the front or vise versa. Instead I am rotating sections, now I am rotating lis to sil and ten to ent and I'm not exactly sure how to rotate letters.
Any help would be greatly appreciated, TY.

What confuses me is the float and string aspect, using the addition portion as an example?
3 + 4
3.5 + 4.25
'hello' + ' world'
The final one confuses me because I am not longer flipping the back with the front or vise versa.
w[2::-1] + w[4:6] + w[3]

Related

Using regex in python to search for floats, and replace them with reduced float precision in a string?

Apologies if this has been answered already - I tried looking it up, but maybe my search terms (same as my title) were bad.
Let's assume I have a string like this, which I don't have control over:
astr = "A 5.02654824574 (14.710000000000008, -19.989999999999995, -0.8) <-> s[10]: A 5.02654824574 (-29.11999999999999, 52.78, -0.8)"
I would like to process this string, so that floats in it are displayed with arbitrary amount of float precision - say 3 decimals. Since this would work on a level of a string, I wouldn't expect the process to account for correct rounding - simply for removal of decimal point string characters.
I'm aware I could do, as per Python: Extract multiple float numbers from string :
import re
p = re.compile(r'\d+\.\d+')
for i in p.findall(astr): print i
... which prints:
5.02654824574
14.710000000000008
19.989999999999995
0.8
5.02654824574
29.11999999999999
52.78
0.8
.... however, I'm getting lost at which regex captures I need to do in a search and replace, so - say, for n_float_precision_decimals = 4, - I'd get this string as output (with the above string as input):
"A 5.0265 (14.7100, -19.9899, -0.8) <-> s[10]: A 5.0265 (-29.1199, 52.78, -0.8)"
So basically, the regex would be taking into account that if there is a smaller number of decimals present already, it would not truncate decimals at all.
Is this possible to do, in a single re.sub operation, without having to write explicit for loops as above, and manually constructing the output string?
Got it - thanks to Reduce float precision using RegExp in swift ( which popped up in SO suggestions only after I finished typing the entire question (during which time, all I got were irrelevant results for this particular question) :) ):
>>> pat=re.compile(r'(\d+\.\d{2})\d+')
>>> pat.sub(r'\1', astr)
'A 5.02 (14.71, -19.98, -0.8) <-> s[10]: A 5.02 (-29.11, 52.78, -0.8)'
... or:
>>> nfloatprec=4
>>> pat=re.compile(r'(\d+\.\d{'+str(nfloatprec)+'})\d+')
>>> pat.sub(r'\1', astr)
'A 5.0265 (14.7100, -19.9899, -0.8) <-> s[10]: A 5.0265 (-29.1199, 52.78, -0.8)'

F-String round float to either 0 or 1 decimals, and how much logic inside an f-string is OK?

I have a bunch of floating point numbers that are either x.0 or x.5 and if they are x.0 I want no decimal points displayed, and if they are x.5 I want one decimal point displayed.
I have come up with a one-liner that does the job:
f'{x:+.{int(bool(x % 1))}f}'
Where int(bool(x % 1)) will always be 0 or 1 depending on whether modulo yields a remainder.
This works fine because of the nature of my float inputs, but it got me thinking, what if my inputs weren't so neat? For example the above one-liner with 10.01 as an input returns 10.0. My temptation is to first round the float to the desired precision:
f'{x:+.{int(bool(round(x, 1) % 1))}f}'
If there wasn't already a lot going on inside the f-string in my first example, there is now.
To be clear about my question:
Firstly, is my first method the 'right' way to go about what I'm actually trying to achieve given my real-world inputs?
Secondly, how about in the case of the hypothetical problem and my second example?
Thirdly, I'd like to canvas opinion from the community regarding where use of f-string crosses the line to abuse. As an example of how one might be tempted to pack a lot of stuff into the f-string, how about something like this to get a list of strings containing numbers to sort alphabetically:
f"String with number:{' ' if x >= 1000 else ' ' if x >= 100 else ' ' if x >= 10 else ' '}{x:+.{int(bool(round(x, 1) % 1))}f}"
So I hope tying this question about overuse of f-string in with my rounding question doesn't cause the overall question to be too vague, but these are two issues that I'm considering together. I suppose the 'neatness' of f-string can provide a temptation to shoehorn everything into one-liners.

Float formatting in Python

While doing this exercise:
>>> amount = 24.325
>>> print("%7f" % amount)
>>> 24.325000
I didn't understand why instead of printing ' 24.325' (whith 1 space before the number) it just added three '0' and didn't move it towards the right at all.
So I thought that maybe, when you don't specify the precision, Python adds '0' until the number has at least 6 digits after the decimal point (if it doesn't already have them) and THAN takes in consideration the width I set (in this case, 7) and adds the needed spaces. In the exercise, with the extra '0's, it ends up having 9 digits, so it didn't add any. Is my hypothesis correct?
The question is, why 6 digits after the decimal point? Is it something that Python does by default?
Thank you.
The python docs exactly describe how the formatting operator % works.
In particular, you can have a minimum field with an a precision.
The former defines the minimum length of your resulting string, the latter gives the number of digits after the decimal point.
As the default precision is 6 for %f, you get what you get.

How do I preserve leading zeros in Python integers for string formatting

I have what I believe to be a simple question. I have the following code and the output is not what I expect:
import socket
import time
r=031508.78
h=373309.9
z=0
mes='"TSRA %s %s %s\r\n"'%(r,h,z)
print mes
My problem is that r prints as '31508.78' and I want '031508.78'. How I get preserve the leading zero?
The 0 in front of the number is not important for python, because numbers have no leading 0s. You can use:
print '%09.2f'%r
I prefer the new string format mini language. I find it more intuitive.
r = 31508.78
h = 373309.9
z = 0
print '"TSRA {0: 011.3f} {1: 011.3f} {2}"\r\n'.format(r, h, z)
print '{0: 011.3f}\n{1: 011.3f}\n{2: 011.3f}'.format(r, h, z)
{0: 011.3f} 0: indicates the first item (r). 011 tells the formatter that there will be 11 characters including the decimal point and a place holder for a negative sign. By placing a 0 in front the formatter will pad the space with leading zeros. Finally, .3f indicates the precision and a fixed number of places after the decimal point.
Yields:
"TSRA 031508.780 373309.900 0"
031508.780
373309.900
000000.000
I don't think there is any way to store a number with a leading zero in python.
This leaves you with two ways:
1) Make r a string i.e. r="031408.78"
I think this is the best method for you as you can do all the arithmetic you want to do (using the implicit typecasting of python) and see the number appended with a 0 wherever you use it.
2) If you simply want to print the number with leading zeros consider using this
print "%09.2f' % r #for this you need the length of the number
For Python, there is no difference in the following things:
31508.78
031508.78
0000000031508.78
31508.7800000000000
0000000000000031508.7800000000000
Those are all valid representations of the exact same number, which is canonically represented by 31508.78, which is essentially just a convention. Different representations are possible too, and actually, the number is represented in a way that’s described by the IEEE-754 standard.
So, when you want that leading zero, you have to tell Python explicitely to put it there because it simply doesn’t know about it. You just used one of many valid representations to specify that one number which default string representation does not include leading zeroes.
The best way to do this is using string formatting, which comes in two flavors. The old style flavor, using the % operator, and the newer str.format function:
>>> '%09.2f' % 31508.78
'031508.78'
>>> '{:09.2f}'.format(31508.78)
'031508.78'
Or, if you don’t actually want a number, you could also just specify the number as a string to begin with, which of course keeps the leading zero.

an error in taking an input in python

111111111111111111111111111111111111111111111111111111111111
when i take this as input , it appends an L at the end like this
111111111111111111111111111111111111111111111111111111111111L
thus affecting my calculations on it .. how can i remove it?
import math
t=raw_input()
l1=[]
a=0
while (str(t)!="" and int(t)!= 0):
l=1
k=int(t)
while(k!= 1):
l=l+1
a=(0.5 + 2.5*(k %2))*k + k % 2
k=a
l1.append(l)
t=raw_input()
a=a+1
for i in range(0,int(a)):
print l1[i]
this is my code and it works for every test case except 111111111111111111111111111111111111111111111111111111111111
so i guess something is wrong when python considers such a huge number
It looks like there are two distinct things happening here. First, as the other posters have noted, the L suffix simply indicates that Python has converted the input value to a long integer. The second issue is on this line:
a=(0.5 + 2.5*(k %2))*k + k % 2
This implicitly results in a floating point number for the value of (0.5 + 2.5*(k %2))*k. Since floats only have 53 bits of precision the result is incorrect due to rounding. Try refactoring the line to avoid floating point math, like this:
a=(1 + 5*(k %2))*k//2 + k % 2
It's being input as a Long Integer, which should behave just like any other number in terms of doing calculations. It's only when you display it using repr (or something that invokes repr, like printing a list) that it gets the 'L'.
What exactly is going wrong?
Edit: Thanks for the code. As far as I can see, giving it a long or short number makes no difference, but it's not really clear what it's supposed to do.
As RichieHindle noticed in his answer, it is being represented as a Long Integer. You can read about the different ways that numbers can be represented in Python at the following page.
When I use numbers that large in Python, I see the L at the end of the number as well. It shouldn't affect any of the computations done on the number. For example:
>>> a = 111111111111111111111111111111111111111
>>> a + 1
111111111111111111111111111111111111112L
>>> str(a)
'111111111111111111111111111111111111111'
>>> int(a)
111111111111111111111111111111111111111L
I did that on the python command line. When you output the number, it will have the internal representation for the number, but it shouldn't affect any of your computations. The link I reference above specifies that long integers have unlimited precision. So cool!
Another way to avoid numerical errors in python is to use Decimal type instead of standard float.
Please refer to official docs
Are you sure that L is really part of it? When you print such large numbers, Python will append an L to indicate it's a long integer object.

Categories