Formatting the opposite of some numbers, with decimal alignment

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite
1












Background



I have a list of strings containing numbers. Each string is 8 characters long. For example :



'-123.456'
' -12.345'
' -1.234'
' 123.456'
' 12.345'
' 1.234'


The longest number possible is ' 999.999' ; the smallest number is ' 0.000' and there always are 3 numbers in the decimal.



What I want to do is compute the opposite of each number, and return it as a string of length 8, with the opposite sign next to the number.



For example :



'-123.456' should yield ' 123.456'
' -12.345' should yield ' 12.345'
' -1.234' should yield ' 1.234'
' 123.456' should yield '-123.456'
' 12.345' should yield ' -12.345'
' 1.234' should yield ' -1.234'


What I did



I wrote the following code, which works :



def opposite(x):
if x.startswith(' -'):
xopp = ' ' + x[3:]
elif x.startswith(' -'):
xopp = ' ' + x[2:]
elif x.startswith('-'):
xopp = ' ' + x[1:]
elif x.startswith(' '):
xopp = ' -' + x[3:]
elif x.startswith(' '):
xopp = ' -' + x[2:]
elif x.startswith(' '):
xopp = '-' + x[1:]
return xopp


My question



I feel like this code is completely "unpythonic" and could be replaced by a one-liner. So the question is: does anyone have an idea to make it more pythonic or even a one-liner ?







share|improve this question



























    up vote
    4
    down vote

    favorite
    1












    Background



    I have a list of strings containing numbers. Each string is 8 characters long. For example :



    '-123.456'
    ' -12.345'
    ' -1.234'
    ' 123.456'
    ' 12.345'
    ' 1.234'


    The longest number possible is ' 999.999' ; the smallest number is ' 0.000' and there always are 3 numbers in the decimal.



    What I want to do is compute the opposite of each number, and return it as a string of length 8, with the opposite sign next to the number.



    For example :



    '-123.456' should yield ' 123.456'
    ' -12.345' should yield ' 12.345'
    ' -1.234' should yield ' 1.234'
    ' 123.456' should yield '-123.456'
    ' 12.345' should yield ' -12.345'
    ' 1.234' should yield ' -1.234'


    What I did



    I wrote the following code, which works :



    def opposite(x):
    if x.startswith(' -'):
    xopp = ' ' + x[3:]
    elif x.startswith(' -'):
    xopp = ' ' + x[2:]
    elif x.startswith('-'):
    xopp = ' ' + x[1:]
    elif x.startswith(' '):
    xopp = ' -' + x[3:]
    elif x.startswith(' '):
    xopp = ' -' + x[2:]
    elif x.startswith(' '):
    xopp = '-' + x[1:]
    return xopp


    My question



    I feel like this code is completely "unpythonic" and could be replaced by a one-liner. So the question is: does anyone have an idea to make it more pythonic or even a one-liner ?







    share|improve this question























      up vote
      4
      down vote

      favorite
      1









      up vote
      4
      down vote

      favorite
      1






      1





      Background



      I have a list of strings containing numbers. Each string is 8 characters long. For example :



      '-123.456'
      ' -12.345'
      ' -1.234'
      ' 123.456'
      ' 12.345'
      ' 1.234'


      The longest number possible is ' 999.999' ; the smallest number is ' 0.000' and there always are 3 numbers in the decimal.



      What I want to do is compute the opposite of each number, and return it as a string of length 8, with the opposite sign next to the number.



      For example :



      '-123.456' should yield ' 123.456'
      ' -12.345' should yield ' 12.345'
      ' -1.234' should yield ' 1.234'
      ' 123.456' should yield '-123.456'
      ' 12.345' should yield ' -12.345'
      ' 1.234' should yield ' -1.234'


      What I did



      I wrote the following code, which works :



      def opposite(x):
      if x.startswith(' -'):
      xopp = ' ' + x[3:]
      elif x.startswith(' -'):
      xopp = ' ' + x[2:]
      elif x.startswith('-'):
      xopp = ' ' + x[1:]
      elif x.startswith(' '):
      xopp = ' -' + x[3:]
      elif x.startswith(' '):
      xopp = ' -' + x[2:]
      elif x.startswith(' '):
      xopp = '-' + x[1:]
      return xopp


      My question



      I feel like this code is completely "unpythonic" and could be replaced by a one-liner. So the question is: does anyone have an idea to make it more pythonic or even a one-liner ?







      share|improve this question













      Background



      I have a list of strings containing numbers. Each string is 8 characters long. For example :



      '-123.456'
      ' -12.345'
      ' -1.234'
      ' 123.456'
      ' 12.345'
      ' 1.234'


      The longest number possible is ' 999.999' ; the smallest number is ' 0.000' and there always are 3 numbers in the decimal.



      What I want to do is compute the opposite of each number, and return it as a string of length 8, with the opposite sign next to the number.



      For example :



      '-123.456' should yield ' 123.456'
      ' -12.345' should yield ' 12.345'
      ' -1.234' should yield ' 1.234'
      ' 123.456' should yield '-123.456'
      ' 12.345' should yield ' -12.345'
      ' 1.234' should yield ' -1.234'


      What I did



      I wrote the following code, which works :



      def opposite(x):
      if x.startswith(' -'):
      xopp = ' ' + x[3:]
      elif x.startswith(' -'):
      xopp = ' ' + x[2:]
      elif x.startswith('-'):
      xopp = ' ' + x[1:]
      elif x.startswith(' '):
      xopp = ' -' + x[3:]
      elif x.startswith(' '):
      xopp = ' -' + x[2:]
      elif x.startswith(' '):
      xopp = '-' + x[1:]
      return xopp


      My question



      I feel like this code is completely "unpythonic" and could be replaced by a one-liner. So the question is: does anyone have an idea to make it more pythonic or even a one-liner ?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 27 at 17:03









      200_success

      123k14142399




      123k14142399









      asked Feb 27 at 16:55









      Deuce

      654




      654




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          5
          down vote



          accepted










          There are only really two things you need here.




          • float. Which allows you to convert the input to a floating point number. If you change to needing more precision or larger numbers, decimal would be a better choice - thanks @200_success. And,


          • str.format. Which uses the Format String Syntax. Which you can use pad the left with spaces, so the output has a width of eight. : >8. This however needs to be adjusted for your "there always are 3 numbers in the decimal" requirement, and so you can force this too with : >8.3f.

          And so I'd use:



          def opposite(x):
          return ': >8.3f'.format(-float(x))



          If however you don't want to use float then you can use str.lstrip. With just one if-else:



          def opposite(x):
          x = x.lstrip()
          if x.startswith('-'):
          x = x[1:]
          else:
          x = '-' + x
          return ': >8'.format(x)





          share|improve this answer























          • This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
            – Deuce
            Feb 27 at 17:10






          • 2




            float is definitely the least hacks solution. Also consider Decimal.
            – 200_success
            Feb 27 at 17:11

















          up vote
          0
          down vote













          I usually hang around python 3.x but I don't think there is any way to make it a one-liner due if you put in an "if" statement, you cannot put in another "if" statement due to which "if" statement is the next line talking about.



          But as for a more efficient way, possible definitely.






          share|improve this answer




























            up vote
            0
            down vote













            There is definitely a way to make it a one liner, which I will post, nevertheless would be interesting to understand what's happening and how to do it



            One liner



            return str(-1 * float(x.strip()))


            But what's happening?



            First, the number you receive contains leading whitespaces, which you want to discard. For that we use the strip function, to get rid of them



            x.strip() # For an input of ' -35' will return '-35'


            Now, we want to convert the number to float, cause is easier and more verbose to calculate the negative value this way. So we cast to float



            float(x.strip())


            Then we multiply by -1 to get the opposite



            -1 * float(x.strip())


            Finally we just need to cast the result to string again, because your function should return a string as you specified



            str(-1 * float(x.strip()))





            share|improve this answer



















            • 1




              Unfortunately this won't work as you'll get: ValueError :)
              – ÑÒ¯Ï…к
              Feb 27 at 17:06






            • 1




              Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
              – Deuce
              Feb 27 at 17:07











            • Well, float will do, will amend :)
              – A. Romeu
              Feb 27 at 17:12










            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188464%2fformatting-the-opposite-of-some-numbers-with-decimal-alignment%23new-answer', 'question_page');

            );

            Post as a guest






























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            5
            down vote



            accepted










            There are only really two things you need here.




            • float. Which allows you to convert the input to a floating point number. If you change to needing more precision or larger numbers, decimal would be a better choice - thanks @200_success. And,


            • str.format. Which uses the Format String Syntax. Which you can use pad the left with spaces, so the output has a width of eight. : >8. This however needs to be adjusted for your "there always are 3 numbers in the decimal" requirement, and so you can force this too with : >8.3f.

            And so I'd use:



            def opposite(x):
            return ': >8.3f'.format(-float(x))



            If however you don't want to use float then you can use str.lstrip. With just one if-else:



            def opposite(x):
            x = x.lstrip()
            if x.startswith('-'):
            x = x[1:]
            else:
            x = '-' + x
            return ': >8'.format(x)





            share|improve this answer























            • This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
              – Deuce
              Feb 27 at 17:10






            • 2




              float is definitely the least hacks solution. Also consider Decimal.
              – 200_success
              Feb 27 at 17:11














            up vote
            5
            down vote



            accepted










            There are only really two things you need here.




            • float. Which allows you to convert the input to a floating point number. If you change to needing more precision or larger numbers, decimal would be a better choice - thanks @200_success. And,


            • str.format. Which uses the Format String Syntax. Which you can use pad the left with spaces, so the output has a width of eight. : >8. This however needs to be adjusted for your "there always are 3 numbers in the decimal" requirement, and so you can force this too with : >8.3f.

            And so I'd use:



            def opposite(x):
            return ': >8.3f'.format(-float(x))



            If however you don't want to use float then you can use str.lstrip. With just one if-else:



            def opposite(x):
            x = x.lstrip()
            if x.startswith('-'):
            x = x[1:]
            else:
            x = '-' + x
            return ': >8'.format(x)





            share|improve this answer























            • This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
              – Deuce
              Feb 27 at 17:10






            • 2




              float is definitely the least hacks solution. Also consider Decimal.
              – 200_success
              Feb 27 at 17:11












            up vote
            5
            down vote



            accepted







            up vote
            5
            down vote



            accepted






            There are only really two things you need here.




            • float. Which allows you to convert the input to a floating point number. If you change to needing more precision or larger numbers, decimal would be a better choice - thanks @200_success. And,


            • str.format. Which uses the Format String Syntax. Which you can use pad the left with spaces, so the output has a width of eight. : >8. This however needs to be adjusted for your "there always are 3 numbers in the decimal" requirement, and so you can force this too with : >8.3f.

            And so I'd use:



            def opposite(x):
            return ': >8.3f'.format(-float(x))



            If however you don't want to use float then you can use str.lstrip. With just one if-else:



            def opposite(x):
            x = x.lstrip()
            if x.startswith('-'):
            x = x[1:]
            else:
            x = '-' + x
            return ': >8'.format(x)





            share|improve this answer















            There are only really two things you need here.




            • float. Which allows you to convert the input to a floating point number. If you change to needing more precision or larger numbers, decimal would be a better choice - thanks @200_success. And,


            • str.format. Which uses the Format String Syntax. Which you can use pad the left with spaces, so the output has a width of eight. : >8. This however needs to be adjusted for your "there always are 3 numbers in the decimal" requirement, and so you can force this too with : >8.3f.

            And so I'd use:



            def opposite(x):
            return ': >8.3f'.format(-float(x))



            If however you don't want to use float then you can use str.lstrip. With just one if-else:



            def opposite(x):
            x = x.lstrip()
            if x.startswith('-'):
            x = x[1:]
            else:
            x = '-' + x
            return ': >8'.format(x)






            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Feb 27 at 17:14


























            answered Feb 27 at 17:03









            Peilonrayz

            24.3k336102




            24.3k336102











            • This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
              – Deuce
              Feb 27 at 17:10






            • 2




              float is definitely the least hacks solution. Also consider Decimal.
              – 200_success
              Feb 27 at 17:11
















            • This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
              – Deuce
              Feb 27 at 17:10






            • 2




              float is definitely the least hacks solution. Also consider Decimal.
              – 200_success
              Feb 27 at 17:11















            This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
            – Deuce
            Feb 27 at 17:10




            This is perfect. I didn't think of format! This is so simple and yet so beautiful :) Thanks!
            – Deuce
            Feb 27 at 17:10




            2




            2




            float is definitely the least hacks solution. Also consider Decimal.
            – 200_success
            Feb 27 at 17:11




            float is definitely the least hacks solution. Also consider Decimal.
            – 200_success
            Feb 27 at 17:11












            up vote
            0
            down vote













            I usually hang around python 3.x but I don't think there is any way to make it a one-liner due if you put in an "if" statement, you cannot put in another "if" statement due to which "if" statement is the next line talking about.



            But as for a more efficient way, possible definitely.






            share|improve this answer

























              up vote
              0
              down vote













              I usually hang around python 3.x but I don't think there is any way to make it a one-liner due if you put in an "if" statement, you cannot put in another "if" statement due to which "if" statement is the next line talking about.



              But as for a more efficient way, possible definitely.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                I usually hang around python 3.x but I don't think there is any way to make it a one-liner due if you put in an "if" statement, you cannot put in another "if" statement due to which "if" statement is the next line talking about.



                But as for a more efficient way, possible definitely.






                share|improve this answer













                I usually hang around python 3.x but I don't think there is any way to make it a one-liner due if you put in an "if" statement, you cannot put in another "if" statement due to which "if" statement is the next line talking about.



                But as for a more efficient way, possible definitely.







                share|improve this answer













                share|improve this answer



                share|improve this answer











                answered Feb 27 at 17:01









                Ghost

                112




                112




















                    up vote
                    0
                    down vote













                    There is definitely a way to make it a one liner, which I will post, nevertheless would be interesting to understand what's happening and how to do it



                    One liner



                    return str(-1 * float(x.strip()))


                    But what's happening?



                    First, the number you receive contains leading whitespaces, which you want to discard. For that we use the strip function, to get rid of them



                    x.strip() # For an input of ' -35' will return '-35'


                    Now, we want to convert the number to float, cause is easier and more verbose to calculate the negative value this way. So we cast to float



                    float(x.strip())


                    Then we multiply by -1 to get the opposite



                    -1 * float(x.strip())


                    Finally we just need to cast the result to string again, because your function should return a string as you specified



                    str(-1 * float(x.strip()))





                    share|improve this answer



















                    • 1




                      Unfortunately this won't work as you'll get: ValueError :)
                      – ÑÒ¯Ï…к
                      Feb 27 at 17:06






                    • 1




                      Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                      – Deuce
                      Feb 27 at 17:07











                    • Well, float will do, will amend :)
                      – A. Romeu
                      Feb 27 at 17:12














                    up vote
                    0
                    down vote













                    There is definitely a way to make it a one liner, which I will post, nevertheless would be interesting to understand what's happening and how to do it



                    One liner



                    return str(-1 * float(x.strip()))


                    But what's happening?



                    First, the number you receive contains leading whitespaces, which you want to discard. For that we use the strip function, to get rid of them



                    x.strip() # For an input of ' -35' will return '-35'


                    Now, we want to convert the number to float, cause is easier and more verbose to calculate the negative value this way. So we cast to float



                    float(x.strip())


                    Then we multiply by -1 to get the opposite



                    -1 * float(x.strip())


                    Finally we just need to cast the result to string again, because your function should return a string as you specified



                    str(-1 * float(x.strip()))





                    share|improve this answer



















                    • 1




                      Unfortunately this won't work as you'll get: ValueError :)
                      – ÑÒ¯Ï…к
                      Feb 27 at 17:06






                    • 1




                      Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                      – Deuce
                      Feb 27 at 17:07











                    • Well, float will do, will amend :)
                      – A. Romeu
                      Feb 27 at 17:12












                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    There is definitely a way to make it a one liner, which I will post, nevertheless would be interesting to understand what's happening and how to do it



                    One liner



                    return str(-1 * float(x.strip()))


                    But what's happening?



                    First, the number you receive contains leading whitespaces, which you want to discard. For that we use the strip function, to get rid of them



                    x.strip() # For an input of ' -35' will return '-35'


                    Now, we want to convert the number to float, cause is easier and more verbose to calculate the negative value this way. So we cast to float



                    float(x.strip())


                    Then we multiply by -1 to get the opposite



                    -1 * float(x.strip())


                    Finally we just need to cast the result to string again, because your function should return a string as you specified



                    str(-1 * float(x.strip()))





                    share|improve this answer















                    There is definitely a way to make it a one liner, which I will post, nevertheless would be interesting to understand what's happening and how to do it



                    One liner



                    return str(-1 * float(x.strip()))


                    But what's happening?



                    First, the number you receive contains leading whitespaces, which you want to discard. For that we use the strip function, to get rid of them



                    x.strip() # For an input of ' -35' will return '-35'


                    Now, we want to convert the number to float, cause is easier and more verbose to calculate the negative value this way. So we cast to float



                    float(x.strip())


                    Then we multiply by -1 to get the opposite



                    -1 * float(x.strip())


                    Finally we just need to cast the result to string again, because your function should return a string as you specified



                    str(-1 * float(x.strip()))






                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Feb 27 at 17:13


























                    answered Feb 27 at 17:01









                    A. Romeu

                    949313




                    949313







                    • 1




                      Unfortunately this won't work as you'll get: ValueError :)
                      – ÑÒ¯Ï…к
                      Feb 27 at 17:06






                    • 1




                      Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                      – Deuce
                      Feb 27 at 17:07











                    • Well, float will do, will amend :)
                      – A. Romeu
                      Feb 27 at 17:12












                    • 1




                      Unfortunately this won't work as you'll get: ValueError :)
                      – ÑÒ¯Ï…к
                      Feb 27 at 17:06






                    • 1




                      Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                      – Deuce
                      Feb 27 at 17:07











                    • Well, float will do, will amend :)
                      – A. Romeu
                      Feb 27 at 17:12







                    1




                    1




                    Unfortunately this won't work as you'll get: ValueError :)
                    – ÑÒ¯Ï…к
                    Feb 27 at 17:06




                    Unfortunately this won't work as you'll get: ValueError :)
                    – ÑÒ¯Ï…к
                    Feb 27 at 17:06




                    1




                    1




                    Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                    – Deuce
                    Feb 27 at 17:07





                    Sorry but this doesn't answer my question : 1. The whole point is to keep the leading spaces to have an 8-characters long string ; 2. Casting to int() won't work, need to use float(). I will update my question to make sure it is understandable that I need to add leading spaces if my string isn't long enough.
                    – Deuce
                    Feb 27 at 17:07













                    Well, float will do, will amend :)
                    – A. Romeu
                    Feb 27 at 17:12




                    Well, float will do, will amend :)
                    – A. Romeu
                    Feb 27 at 17:12












                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188464%2fformatting-the-opposite-of-some-numbers-with-decimal-alignment%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    Greedy Best First Search implementation in Rust

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    C++11 CLH Lock Implementation