Friday, May 6, 2011

Can my file (image) names be too long?

When outputting images from Photoshop that are over 31 characters I get a compatibility message? Is there a downside to making image names (or any filenames) too long?

I want to make sure my web app displays my images correctly in all major browsers, including mobile, and that my image names get picked up by Google for indexing.

For example, if I have a Ford Thunderbird that I am selling, ideally I'd like my image name to be nice and descriptive for both usability and rankings, ie ford_thunderbird_sports_car_large.jpg .. the large would be the file size, vs thumbnails...

however that's a longer filename that may cause some browsers to not see it..

anyone have ideas? what are best practices for 2009?

From stackoverflow
  • I think the best place to store those descriptive data would be the image's metadata (this should be possible to edit in Photoshop), that would be a way of making the filename shorter and still keeping the descriptions (you can still use some flags or abbreviations in the filename, though).

    EDIT: Here's a workaround for Photoshop to not give a warning. It seems that this is some Mac-specific thing.

    jim : never thought of that, but I know Google is looking for those keywords in the image filename.. i didnt realize though that that 31 char limit referred to Mac OS9..ancient anyway! thanks
  • I'm pretty sure the maximum file length in any modern OS is at least 255 characters. Here's a wikipedia link: Comparison of file systems

    As for the web, I doubt you'll hit these limits. You should be fine.

    jim : thanks, I'm not worrying about this anymore :)

OSGi SAT, how should we deal with activation failure?

The eclipse OSGi Service Activator Toolkit provides a framework that simplifies handling the dependencies between budles.

One can derive from org.eclipse.soda.sat.core.framework.BaseBundleActivator and over-ride (for example) the activate() method to do some spefic initialisation work.

The signature is protected void activate(){}

Which leads to the question: "what are we spposed to do if activate() fails?", suppose for some reason we cannot initialise correctly. I can't throw an exception, the method signatiure won't allow that.

From stackoverflow
  • It's still possible to throw RuntimeException and Error (And Exceptions that inherit these). (Remember that Error indicates serious problems that a reasonable application should not try to catch.)

    It would also seems like a good idea to output something to your logging facility.

    The alternative you choose is dependent on the situation; what the root cause of the failed activation is. If the cause is something abnormal, that should not happen during normal circumstances, an Error or RuntimeException (and ofcourse loggin) feels right.

    djna : I agree that emiting some diagnostics is a good idea. I'm not sure about the unchecked exceptions. In general, yes I could throw an unchecked exception. However is this valid in the context of this framework? I would expect the framwork to define the error handling "protocol" by specifying an exception to throw.
  • Throwing an RuntimeException or an Error in the activate() method does not help you if you are using Equinox (tested with org.eclipse.osgi_3.5.1.R35x_v20090827). Independent of what you are throwing the bundle will finally end up in state ACTIVE.

    I assume that this behavior is specific to Equinox (bug?) because from my understanding this violates the OSGi specs.

    djna : It does seem to be difficult to know exactly what to do in these cases. I believe that the SAT authors should explcitly define what we should do.

How do I create an SQL query that groups by value ranges

I would like to create a sql query that reports the percentage of results in a particular range. for instance

20% of the values between 10 to 20

40% of the values between 20 to 32.5

Server - MSSQL

From stackoverflow
  • GROUP BY CASE 
             WHEN VALUE >= 10 AND VALUE <= 20 THEN '20%'
             WHEN VALUE > 20 AND VALUE <= 32.5 THEN '40%' ELSE '0' END
    

    You need to cover all possible values, hence the ELSE 0. You'll probably want to do something a little different there, but it should give you a start.


    Based on Joel Gauvreau's comment:

    SUM(CASE WHEN VALUE >=10 AND VALUE <= 20 THEN 1.0 ELSE 0.0 END) / COUNT(*),
    SUM(CASE WHEN VALUE > 20 AND VALUE <= 32.5 THEN 1.0 ELSE 0.0 END) / COUNT(*)
    

    Or at the end of the query use the COMPUTE statement.

    Joel Gauvreau : I Think he meant the distribution of the values by range. 200 records where value is in the range between 10 and 20 would results what percentage of the total number of records...
    Joel Coehoorn : Ah, thanks. Updated my answer.
    Andomar : +1 best idea, but needs a cast from integer to float, and an extra ) for the sum on the second line
  • This will get you the count per range, you can easily determine the percentage from there:

    declare @ranges table (beginInclusive float, endExclusive float)
    insert @ranges (beginInclusive, endExclusive)
        select 10, 20
        union all select 20, 32.5
    
    select
        r.beginInclusive,
        r.endExclusive,
        count(*)
    from t join @ranges on t.RangedValue >= r.beginInclusive and t.RangedValue < r.endExclusive
    group by 
        r.beginInclusive,
        r.endExclusive
    
  • I would usually use a subquery and get rangecounts and join in the total to get the percentage. Something like:

    SELECT 
      RangeCount/CNT as Percentage,
      Range
    FROM 
    (
    SELECT
      Count(*) AS CNT
    FROM
      SomeTable
    ) AS Total
    LEFT JOIN 
    (
    SELECT
      CASE Val <= 10 then
           '0 up to 10'
      ELSE 
           CASE when Val <= 20
             '11 to 20'
           ELSE 
            '> 20'
           END
        END
      END AS Range,
      COUNT(*) AS RangeCount
    FROM 
       SomeTable
    GROUP BY
       Range
    ) AS RangeTotals
    
  • SELECT B.Description, Total = COUNT(*) / CONVERT(money, (SELECT COUNT(*) FROM Target T2))
    FROM Target T
    JOIN (
        SELECT  Description = '0 to 10', LBound = 0, UBound = 10 
        UNION ALL 
        SELECT Description = '10 to 20', LBound = 10, UBound = 20
    ) B ON T.Value >= LBound AND T.Value < B.UBound
    GROUP BY B.Description
    
  • Declare @1 as int
    Declare @2 as int
    Declare @TotalRows as int
    
    set @1 = (Select COUNT(id) FROM dbo.Table_1 WHERE id >= 10 and id <= 20)
    set @2 = (Select COUNT(id) FROM dbo.Table_1 WHERE id > 20 AND id <= 32.5);
    set @TotalRows = (Select Count(id) from dbo.Table_1);
    
    SELECT CAST(((@1 * 100)/@TotalRows) as nvarchar(32)) + '%', CAST(((@2 * 100)/@TotalRows) as nvarchar(32)) + '%';
    

    Little complicated, but that does work... i suppose...

    dbo.Table_1 only has 1 column, 'id' and it is of type int.

  • If it's something that you will be doing regularly, then you can create a table with the ranges and what constitutes those ranges. If not, you can set them up in a table variable or temporary table and join to that. It's basically JohnOpincar's solution, but with a table instead of a subquery.

    Also, in your example you list "10 to 20" and "20 to 32.5". Where is a row counted if it's exactly 20? You should probably make sure that your requirements are clear on that point before you deliver the final solution.

  • Joel's answer seems the best way to me. Posting to explain the query, and because the answer has an integer division sum/count which will return 1 or 0 instead of a percentage.

    For the 20 -> 32.5 range:

    select CAST(SUM(
        CASE WHEN 20 < field AND field <= 32.5 THEN 1 ELSE 0 END
        ) as float) / COUNT(*) * 100.0
    from table
    

    The case returns 1 when the value is in range. Because there's no group by clause, the sum adds the result of the case for every row in the table. Convert to float, divide by the number of rows =count(*), and you get the percentage.

    You can also write it like:

    select SUM(
        CASE WHEN 20 < field AND field <= 32.5 THEN 1.0 ELSE 0.0 END
        ) / COUNT(*) * 100
    from table
    

    Here the CASE will result in a float 1.0 instead of the integer 1.

popen() in C

I can run the following command

xwd -root | xwdtopnm | pnmtojpeg > screen.jpg

in a terminal under linux and it will produce a screenshot of my current screen.

I try to do the following with the code:

#include <stdio.h>
#include <stdlib.h>
int main()
{
   FILE *fpipe;
   char *command="xwd -root | xwdtopnm | pnmtojpeg";
   char line[256];

 if ( !(fpipe = (FILE*)popen(command,"r")) )
{  // If fpipe is NULL
   perror("Problems with pipe");
   exit(1);
 }

while ( fgets( line, sizeof line, fpipe))
{
  //printf("%s", line);
  puts(line);
}
pclose(fpipe);
}

then I compile and run the program ./popen > screen.jpg but the resulting file screen.jpg is unrecongizable. How can I do this so that I can pipe through my program?

From stackoverflow
  • Without testing your code I hav doubts that "xwd -root | xwdtopnm | pnmtojpeg" works as an argument for a C - Pipe.

    I wouldn't use a C program anyway for such a problem. Use a simple Bash script instead.

  • You shouldn't use fgets and puts for dealing with binary data. fgets will stop whenever it sees a newline. Worse, puts will output extra newlines and it will also stop whenever it runs into a \0. Use fread and fwrite instead.

    Laurence Gonsalves : Sorry, I meant fread and fwrite, not read and write. (just edited my answer)
  • The functions fgets and puts aren't intended to be used with binary data like image files. They should only be used with strings of text. In C, strings end with a null byte ('\0'). Since that's really just a zero, it might appear anywhere in a binary file. Let's say that line[] is filled with 256 characters of data. When you call puts, the function reads the array until it encounters a null byte then assumes it has reached the end of the string and stops. Since in a binary file a null byte might appear anywhere (and not just at the end of the array), the puts function could easily fail to print out sections of your data.

    If I were you, I'd research the fread and fwrite functions and use them instead. On a Linux machine, you should just be able to type man 3 fread to read documentation for both functions.

  • For those having this same problem, I ended up finally getting it working by using the Unix read/write system calls:

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    
    //writes to an output file test.jpg directly
    int main()
    {
     FILE *fpipe;
     char *command="xset b off  && xwd -root | xwdtopnm 2> /dev/null | pnmtojpeg";
     char buff[256];
     size_t result_write;
     size_t result_read;
    
     if ( !(fpipe = (FILE*)popen(command,"r")) )
     {  // If fpipe is NULL
      perror("Problems with pipe");
      exit(1);
     }
    
     int dest_fd = open("test.jpg",  O_RDWR|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR );
     int fd = fileno(fpipe);
     while((result_read = read(fd, buff, sizeof(char)*256))>0){ 
      if(result_read < 0){
       perror("Problem while reading.\n");
       exit(1);
      }
      result_write = write(dest_fd, buff, sizeof(char)*256);
      if(result_write < 0){
       perror("Probelms writing to outputfile.\n");
       exit(1);
      } 
     }
     close(dest_fd);  
       pclose(fpipe);
    }
    
    ephemient : As long as you make sure not to perform buffered IO (fread, fscanf, fwrite, fprintf, ...) and unbuffered IO (read, write, ...) on the same file, this should be fine. Don't understand why you didn't just use fread and fwrite, though.

C++ constructor problem

#include <iostream>
using namespace std;

// This first class contains a vector and a scalar representing the size of the vector.
typedef class Structure1
{
 int N;
 double* vec;
public: 
 // Constructor and copy constructor:
 Structure1(int Nin);
 Structure1(const Structure1& structurein);
 // Accessor functions:
 int get_N() { return N; }
 double* get_vec() { return vec; }
 // Destructor:
 ~Structure1() { delete []vec; }
} Structure1;

Structure1::Structure1(int Nin)
{
 N = Nin;
 vec = new double [N];
 for (int i = 0; i < N; i++)
  {
   vec[i] = i;
  };
}

Structure1::Structure1(const Structure1& structurein)
{
 vec = new double[structurein.N];
 for(int i = 0; i < structurein.N; i++)
 {
  vec[i] = structurein.vec[i];
 };
}

// This class just contains the first structure.
typedef class Structure2
 {
  Structure1 structure;
 public:  
  // Constructor:
  Structure2(const Structure1& structurein) { structure = structurein; }

The error occurs here:

Line Location main.cpp:47: error: no matching function for call to 'Structure1::Structure1()'

  // Accessor Function:
  Structure1 get_structure() { return structure; }
  // Destructor:
  ~Structure2() {}
 } Structure2;

int main (int argc, char * const argv[])
{
 const int N = 100;
 Structure1 structure1(N);
 Structure2 structure2(structure1);

 return 0;
}

If anyone knows what's wrong, your help would be greatly appreciated. Thanks!

From stackoverflow
  • You need to use a member initializer in your Structure2 ctor.

    Structure2(const Structure1& structurein) : structure(structurein) {}
    

    It's trying to use a default constructor for your Structure1 member, and there isn't one.

  • Since you have declared a constructor for Structure2, the compiler refuses to create a default constructor for it which is needed in order to access members of the class like you do in this constructor:

      Structure2(const Structure1& structurein) { structure = structurein; }
    

    You should probably do:

    Structure2(const Structure1& structurein) : structure(structurein) {}
    
  • By the way, I think you need to fix the copy constructor:

    Structure1::Structure1(const Structure1& structurein)
    {
     ///!!!! Initialize N
     N = structurein.N;
    
     vec = new double[structurein.N];
     for(int i = 0; i < structurein.N; i++)
     {
      vec[i] = structurein.vec[i];
     };
    }
    
    ypsu : At the beginning you should make sure you are constructing the object from an another object, like if (this == &structurein) return; Otherwise your copy won't work, and also a memory leak we'll be there as well.
    ypsu : Ah, sorry,ignore my previous commentt, I mixed this this with the = operator! :)
    ypsu : Sorry for spamming, but you can still construct the object from the same object: new (&b) A(b); Calling placement new with the same address where as the object from which A is constructed is rare, maybe you can ignore this.

iPhone: What is Springboard? Do I need to care?

When creating iPhone apps in simulator, I sometimes see messages like "Springboard failed to launch application", etc.

What is Springboard? Are there things I should know about it as a developer?

From stackoverflow
  • Springboard is just the iPhone home screen application.

    This related question may help.

  • Springboard is the launcher application -- i.e. the one you see on the home screen with all the tiled app icons.

    I don't think there's anything more you really need to know about it.

  • Springboard is the iPhone emulator that your app runs within. If Springboard only periodically fails to launch your app, something's probably wrong with Springboard, but if your app won't launch at all, there's probably something wrong with your app (and if it was deployed on a real phone, wouldn't launch there, either).

What sort function is used in NSArray?

This is really a three-part question, but I've answered the first question myself:

I'm working on the iPhone, with many objects (up to 200) on the screen. Each object needs to look if it's overlapping other objects, and act accordingly. My original naive implementation was for each object to run through the list of each other object to check their bounding boxes (using CGRectInsersectsRect).

So my question (and answer) is what's a better method? My new implementation is to sort the array every frame using an insertion sort (since the data will be mostly sorted already) on the y-position of each object, then check only the nearest object on either side of the one searching, to see if it's in range vertically, then check horizontally.

First question: Is insertion sort the method I want to use for an array of objects that tend to move around randomly but only to a small extent so they mostly stay in order based on the last frame? Also: what sort algorithm does the NSArray use when I call

- sortedArrayUsingSelector:

I would sort of assume that it uses a quick sort, since it's the most useful in the general case. Does anybody know if I'm wrong? Does anybody know if I can change the sort method or if I will have to write my own sorting function?

Second question: is there a function for retrieving items from a sorted array using a binary search, rather than the naive approach that I assume is used by

- indexOfObject:

or would I have to write my own?

From stackoverflow
  • NSArray uses many different data structures internally depending on how many objects are in the array. See a Peter Ammon blog entry for more information. But basically this means you can't expect a certain kind of sort to happen. Sometimes it is worth it to write your own array implementation using C arrays so you can control the sorts yourself.

    There are definitely much faster ways to implement collision detection. Look into Bounding Volume Hierarchies like KD Trees or similar.

    As far as I know indexOfObject: is the only way, but it's potentially not as dumb as you think. Everything is hashable for NSDictionary so they can use some of those smarts in NSArray.