Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Easier in bash, python, C ? Which is quickest?

  1. #1
    Join Date
    Jan 2007
    Location
    Toronto ON Canada
    Beans
    1,127
    Distro
    Xubuntu

    Easier in bash, python, C ? Which is quickest?

    I have a fairly simple task in mind, but am not sure what best to tackle it with. My knowledge is insufficient to be sure of any of them!

    What I want to do is resolve the following:
    Code:
        Given: 2 times, one smaller (lesser) than the other
       Format: most often mm:ss - sometimes hh:mm:ss (minimum known :ss - maximum known h:mm:ss)
    Determine: total seconds in each
    Calculate: percentage that the smaller is of the larger
       Return: that percentage (on stdout) or zero
    I can't think of any reason it cannot be done with any of them, but my years with 'C' are further in the past than I care to think about (though not beyond retrieval) - my python is non-existent (but looks easy to learn enough for this(dare I sat BASIC like?)) and bash looks like it might be convoluted to attempt at my level of familiarity with it! On top of all that, the time and resources required should be small, as it will be called frequently.

    Any suggestions/recommendations/alternatives from the experts out there? I don't want to sink too much effort and time into the wrong choice
    | Xubuntu 20.04 / Arch rolling XFCE/ MX-19 patito feo / Arcolinux 20.5.7 rolling / EndeavourOS rolling XFCE / Ubuntu Unity 20.04 / Arch rolling Cinnamon / EndeavorsOS rolling Budgie / Arch rolling XFCE-compiz / Kubuntu 20.04 |

  2. #2
    Join Date
    Jul 2005
    Beans
    382

    Re: Easier in bash, python, C ? Which is quickest?

    Python, absolutely no question! Look at the 'time' module (part of the built in modules) It will handle all the conversions and the rest is just maths.
    Registered Linux User #407403

  3. #3
    Join Date
    Jan 2007
    Location
    Toronto ON Canada
    Beans
    1,127
    Distro
    Xubuntu

    Re: Easier in bash, python, C ? Which is quickest?

    Well - I took another look at Python - and I just can't get my head around the weird ways it does things... some of them seem designed just to be different where no advantage is gained

    Bash - still don't know enough - especially for testing purposes...

    So - back to 'C' - the old-fashioned way. A little popen(), a little strtok() and a little sscanf() took care of it. Oh - I mean the old-fashioned way - heavily commented the source is only 2.5K - and the executable is 13.4K so it shouldn't be too slow for its intended purpose. Now to integrate its results into conky....

    I'll just mark it [SOLVED] - 'cos in a way it is.
    | Xubuntu 20.04 / Arch rolling XFCE/ MX-19 patito feo / Arcolinux 20.5.7 rolling / EndeavourOS rolling XFCE / Ubuntu Unity 20.04 / Arch rolling Cinnamon / EndeavorsOS rolling Budgie / Arch rolling XFCE-compiz / Kubuntu 20.04 |

  4. #4
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Easier in bash, python, C ? Which is quickest?

    lol, how frequently do you call your prog in conky that you need C performance?

    in bash and python it would be like 10 lines tops.

    eg bash
    Code:
    #!/bin/bash
    
    t1=$1
    t2=$2
    
    # normalize format to h:m:s
    until [[ $t1 = *:*:* ]]; do t1=0:$t1; done
    until [[ $t2 = *:*:* ]]; do t2=0:$t2; done
    
    # parse normalized time1, calculate seconds
    IFS=: read hh mm ss <<< "$t1"
    (( hh=10#$hh, mm=10#$mm, ss=10#$ss ))
    s1=$(( hh*3600+mm*60+ss ))
    
    # parse normalized time2, calculate seconds
    IFS=: read hh mm ss <<< "$t2"
    (( hh=10#$hh, mm=10#$mm, ss=10#$ss ))
    s2=$(( hh*3600+mm*60+ss ))
    
    # determine numerator, denominator
    (( s1>s2?(n=s2, d=s1):(n=s1, d=s2) ))
    # print percentage (rounded)
    printf '%d%%\n' $(( (100*10*n/d+5)/10 ))
    # print percentage (truncated)
    #printf '%d%%\n' $(( (100*n/d ))
    Code:
    $ ./pcent.sh 59 0:0:59
    100%
    $ ./pcent.sh :59 1:0:59
    2%
    $ ./pcent.sh 29:59 1:0:0
    50%
    Last edited by Vaphell; April 16th, 2014 at 04:04 PM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  5. #5
    Join Date
    Jan 2007
    Location
    Toronto ON Canada
    Beans
    1,127
    Distro
    Xubuntu

    Re: Easier in bash, python, C ? Which is quickest?

    Quote Originally Posted by Vaphell View Post
    lol, how frequently do you call your prog in conky that you need C performance?

    in bash and python it would be like 10 lines tops.
    Well - minimum would be about every 2 seconds, maximum would be once a second I suppose. It is not just the performance, it is that you get the whole python interpreter loaded - however small the code! Assuming I have that information right, of course

    Also - the input comes from another program running, and thus I open it with a pipe from mine, then process as described. I ended up with about 44 lines (including declarations - not including 'prettifying' and comments) so it wasn't too bad! I'm a bit hesitant to post it (showing how out of practice (and old-fashioned) I am) but I will if anyone wants to see it...

    Thanks - I knew the code would be short in Python - but the process of figuring how to generate it would be long (it took me a few hours of looking through documentation to decide it wouldn't do for me for this!). Now all I have to do is figure how to ship the answer I get over to a lua routine for display (can't find a 'user' variable in conky, and I don't know any other way yet to pass it).

    On we go.....
    | Xubuntu 20.04 / Arch rolling XFCE/ MX-19 patito feo / Arcolinux 20.5.7 rolling / EndeavourOS rolling XFCE / Ubuntu Unity 20.04 / Arch rolling Cinnamon / EndeavorsOS rolling Budgie / Arch rolling XFCE-compiz / Kubuntu 20.04 |

  6. #6
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Easier in bash, python, C ? Which is quickest?

    yes, overhead might be a problem. Minimizing number of processes would be nice. So where do you get these times from?

    btw, if you feel like reverse engineering to understand it, a simple python solution

    Code:
    #!/usr/bin/env python
    
    import sys
    
    def time2sec( t ):
        l = [ int('0'+x) for x in t.split(':') ]
        for i in range(0, 3-len(l)):
            l.insert( 0, 0 )
        return sum( 60**(2-i)*l[i] for i in range(0, len(l)) )
    
    n, d = sorted( time2sec(p) for p in sys.argv[1:3] )
    
    # .1: precision, %: percentage
    print '{0:.1%}'.format( 1.0*n/d )
    Last edited by Vaphell; April 16th, 2014 at 10:11 PM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  7. #7
    Join Date
    Jan 2007
    Location
    Toronto ON Canada
    Beans
    1,127
    Distro
    Xubuntu

    Re: Easier in bash, python, C ? Which is quickest?

    Quote Originally Posted by Vaphell View Post
    yes, overhead might be a problem. Minimizing number of processes would be nice. So where do you get these times from?

    btw, if you feel like reverse engineering to understand it, a simple python solution

    Code:
    #!/usr/bin/env python
    
    import sys
    
    def time2sec( t ):
        l = [ int('0'+x) for x in t.split(':') ]
        for i in range(0, 3-len(l)):
            l.insert( 0, 0 )
        return sum( 60**(2-i)*l[i] for i in range(0, len(l)) )
    
    n, d = sorted( time2sec(p) for p in sys.argv[1:3] )
    
    # .1: precision, %: percentage
    print '{0:.1%}'.format( 1.0*n/d )

    Well - simple if you know it I guess! However, I don't see handling of 'outliers' - hour+ times...

    For the laugh - here's the (old-style) 'C'
    PHP Code:
    /* calculate percentage of song played for graph */

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    long elapseddurationlength;
    double percent;
    char data[20];
    char *times[2][10];
    const 
    char delimit[2]=" \n"/*for strtok - split elapsed and duration - and lose the newline */

    void GetData(char *data);  /*buffer for redirect ouput from rhythmbox-client */
    long CalcSeconds(char *timestrlong length);

    main()
        {
        
    /* run rhythmbox-client */
        
    GetData(data);
        
    /* split up returning elapsed and duration data */
        
    times[0][0] = strtok(datadelimit);
        if (
    times[0][0] != NULL)
            {   
            
    times[1][0] = strtok(NULLdelimit);
            } 
    /*endif*/
        /* process from hh:mm:ss into total seconds */
        
    elapsed=CalcSeconds(times[0][0], strlen(times[0][0]));
        
    duration=CalcSeconds(times[1][0], strlen(times[1][0]));
        
    /* calculate percentage */
        
    percent=(elapsed*100)/(float)duration;
        
    /* dump result to stdout */
        
    printf("%3.f\n",percent);
        exit(
    0);    
        } 
    /* end main */

    void GetData(char *data)
        {
        
    FILE *pf;
        
    char command[100]="rhythmbox-client --print-playing-format '%te %td'";
     
        
    /* Setup our pipe for reading and execute our command. */
        
    pf popen(command,"r"); 
     
        if(!
    pf)
            {
            
    fprintf(stderr"Could not open pipe for output.\n");
            return;
            } 
    /* endif */
     
        /* Grab data from process execution */
        
    fgets(data100 pf);
     
        if (
    pclose(pf) != 0)
            {
            
    fprintf(stderr," Error: Failed to close command stream \n");
            } 
    /* endif */
        
    return;
        } 
    /* end GetData */

    long CalcSeconds(char *timestrlong length)
        {
        
    long hr=0,min=0,sec=0,result=0;
        
    char *token[3][3];
        const 
    char delim[2] = ":";
     
        
    /* get the first token */
        
    token[0][0] = strtok(timestrdelim);
        
    /* convert to numeric value */
        
    sscanf(token[0][0],"%ld",&hr);
        
    /* walk through other tokens */
        
    if (token[0][0] != NULL)
            {   
            
    token[1][0] = strtok(NULLdelim);
            
    sscanf(token[1][0],"%ld",&min);
            } 
    /*endif*/
        /* use string length to show if hours are present */
        
    if (length>5)
            { 
            
    token[2][0] = strtok(NULLdelim);
            
    sscanf(token[2][0],"%ld\n",&sec);
            } 
    /*endif*/
        
    else
            {
            
    /* move entries to correct places for value */
            
    sec=min;
            
    min=hr;
            
    hr=0;
            } 
    /*endif*/
        /* calculate total seconds */
        
    hr=hr*3600;
        
    min=min*60;
        
    result=hr+min+sec;
        return(
    result);
        } 
    /* end CalcSeconds */ 
    As you see, I 'split' the incoming data into 2 separate strings (I'd be using argc() and arg v() if I were running it directly), then split each in the function on the ':' before making them into numbers and sending them back for calculating. Overcommented too - a habit from having to figure out what I did a couple of years later too often!

    Thanks..
    Last edited by freebird54; April 17th, 2014 at 02:42 AM.
    | Xubuntu 20.04 / Arch rolling XFCE/ MX-19 patito feo / Arcolinux 20.5.7 rolling / EndeavourOS rolling XFCE / Ubuntu Unity 20.04 / Arch rolling Cinnamon / EndeavorsOS rolling Budgie / Arch rolling XFCE-compiz / Kubuntu 20.04 |

  8. #8
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Easier in bash, python, C ? Which is quickest?

    damn, quite a lot of boilerplate

    well, i figured out i don't need fixed 3 elem data structure so i shortened the code

    Code:
    #!/usr/bin/env python
    
    import sys
    
    def time2sec( t ):
        l = [ int('0'+x) for x in t.split(':')[::-1] ]
        return sum( 60**i*l[i] for i in range(0,len(l)) )
    
    n, d = sorted( time2sec(p) for p in sys.argv[1:3] )
    
    print '{0:.1%}'.format( 1.0*n/d )
    sys.argv[1:3] are argv[1] and argv[2] (think for(i=1; i<3; i++) { argv[i] } ).
    Both params are sent to time2sec() to return seconds. Sorted() puts them in order so n is always <= than d.

    time2sec function splits the param on ':' which yields a list (array) of substrings with 1-3 elems, reverses it ([::-1]) and for each elem converts to int. That '0' is to deal with empty strings so you can have '1::' understood as '1:00:00' because why not
    tl;dr: l is a reversed list of ints (with m and h optionally missing if they were not in the input).
    This order allows for automagical sum( l[i]*60^i ) for all existing elements, that is
    s*60^0 for s
    s*60^0+m*60^1 for m:s
    s*60^0+m*60^1+h*60^2 for h:m:s

    once n and d are calculated, print n/d.


    Code:
    $ ./pcent.py 1::3 2:11
    3.6%
    $ ./pcent.py :30 2:11
    22.9%
    $ ./pcent.py 2:11 30
    22.9%
    so the relevant command is
    Code:
    rhythmbox-client --print-playing-format '%te %td'
    in the bash script i posted it would be enough to have this at the top instead of $1 and $2
    Code:
    read t1 t2 < <( rhythmbox-client --print-playing-format '%te %td' )
    Last edited by Vaphell; April 17th, 2014 at 02:22 AM.
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

  9. #9
    Join Date
    Jan 2007
    Location
    Toronto ON Canada
    Beans
    1,127
    Distro
    Xubuntu

    Re: Easier in bash, python, C ? Which is quickest?

    Yup - never claimed any efficiencies in the coding! I see there are lots of neat features in that - but learning them (and realigning the brain to think in objects rather than event-driven) would take far longer than writing the extra code did. Not to mention that I would have no idea where to start if it didn't run right away... for me debuggers are supposed to show me 680x0 machine code!

    Are any of the compiled BASIC's worth anything for quick and dirty 'old-stylers' like myself? Or pehaps a Modula-2? Or do I have to try to modernize?
    | Xubuntu 20.04 / Arch rolling XFCE/ MX-19 patito feo / Arcolinux 20.5.7 rolling / EndeavourOS rolling XFCE / Ubuntu Unity 20.04 / Arch rolling Cinnamon / EndeavorsOS rolling Budgie / Arch rolling XFCE-compiz / Kubuntu 20.04 |

  10. #10
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Easier in bash, python, C ? Which is quickest?

    sure, you won't get much help from python with your current problem but imo it's beneficial to know it or some other higher level language that doesn't require 2 pages of code to read and trivial interpret input. Quoting one black lady "Ain't nobody got time for that"

    google, stack overflow and docs.python.org and you are golden
    if your question is answered, mark the thread as [SOLVED]. Thx.
    To post code or command output, use [code] tags.
    Check your bash script here // BashFAQ // BashPitfalls

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •