Formatting the opposite of some numbers, with decimal alignment

Multi tool use
Multi tool use

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













































































                    ZDLGaepR,vEtcZeuN3rF3o US57iNrQ4tOUJWH9e
                    WAnt TeKAm6x,ZE wup0ED2EePJZR

                    Popular posts from this blog

                    Chat program with C++ and SFML

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

                    Read an image with ADNS2610 optical sensor and Arduino Uno