Counting chars.

edited August 2015 in How To...

Hello there! i have a .txt file composed by words separated by commas. I loaded it into Processing, and joined all the lines and i would really like my program to go through the text and only print the commas at the right position(for example, if i have something like this: "word 1,word 2,word 3,..." i would really like to be able to have this " , , ,..." where the blanks represent exactly the number of the words' chars, symbols and spaces (in this case there are 6 blanks and a comma, since "word 1" is formed by 6 chars). Now, the output i would like to have is a continuous horizontal text made of commas, but i am afraid i am unable to break down the workflow and to understand how can i achieve this.

can anybody help me understand the direction to take? I am not asking for code, but just for a hint regarding what to consider and where to watch.

Thank you very much!

Answers

  • edited August 2015

    show your code....

    use split() with ','

    then for-loop over it, use length() on each entry in the array and insert as many ' ' as length() returned

  • thank you for your pointers!(sorry for the late reply!) here is my code till now:

      String[] words;
    
      void setup() {
      size(600, 600);
      String[] s = loadStrings("Stream of Consciousness #1.txt");
      String entiretext = join(s, ",");
      String[] words = split(entiretext, ",");
      printArray(words);
      }
    
      void draw() {
        background(255);
        for(int i = 0; i < words.length; i++) {
          line(words.length(), 0, words.length(), height);
        }
      }
    

    here i should have an array of words and a for loop iterating through the array. i am trying to draw a line at the end of every word, but i can't use length() on words, since words is an array. but if i run words.length the returned value will be the length of the array. i am now looking for a solution in the reference pages but my doubt remains.

  • Answer ✓

    for (String w : words) line(w.length(), 0, w.length(), height);

  • that's amazing! thank you both for helping me out! i guess what i missed (i am really blind) was the existence of the for ( : ) loop. i have always used the other version. thank you thank you! it worked! now i am on my way to understanding how to draw the lines not all starting from the same spot, but from the previous line! cheers!

  • ... how to draw the lines not all starting from the same spot, ...

    Dunno what's the exactly layout you wish to achieve but here's a start:

    static final int GAP = 4;
    
    void draw() {
      background(-1);
      int v = 0;
      for (String w : words)  line(0, v += GAP, w.length(), v);
    }
    

    And the same above w/ traditional for ( ;; ) loop: :D

    static final int GAP = 4;
    
    void draw() {
      background(-1);
      for (int v = 0, len = words.length; v != len; ++v)
        line(0, v*GAP, words[v].length(), v*GAP);
    }
    
  • edited August 2015

    so, the two pieces of code you just posted really helped me out in figuring how to approach the problem! i tried to apply the second method you indicated and now i have something like this:

      String[] words;
      static final int GAP = 10;
    
    void setup() {
      size(1600, 600);
      String[] s = loadStrings("Stream of Consciousness #1.txt");
      String entiretext = join(s, ",");
      words = split(entiretext, ",");
      //printArray(words);
    }
    
    void draw() {
      background(255);
    
      for (int v = 0, len = words.length; v != len; ++v){
    
      line(words[v].length()+ v*GAP, 0, words[v].length()+ v*GAP, height);
      }
    }
    

    tell me if i am wrong: thanks to GAP i can scale up and down the entire visualisation, and the lines are drawn basically at the end of every word length. so if i have dog the line is drawn before the d and after the g. it looks like it is working, but i feel that something is still wrong. i don't know why but sometimes the lines don't reflect the real length of the word. i am going to test this with another text, in which i alternate the length of the words in a more evident way! all of this was just to say: thank you for the help! :)

    edit: after some testing i can affirm that the length of the words is not represented. ._.

  • String[] words;
    static final int GAP = 20;
    
    void setup() {
      size(1600, 600);
      //String[] s = loadStrings("Stream of Consciousness #1.txt");
      String[] s = {
        "Stream of Consciousness 1 txt, hello, good day", "nice"
      };
      String entiretext = join(s, ",");
      words = split(entiretext, ",");
      //printArray(words);
    }
    
    void draw() {
      background(255);
    
      int len = words.length;
    
      for (int v = 0; v < len; v++) {
        stroke(0); 
        line(words[v].length()+ v*GAP + 32, 0, words[v].length()+ v*GAP + 32, height);
        stroke(255, 2, 2); 
        int yValue = v*GAP + 22;
        fill(255, 2, 2);
        line(0, yValue, 
        words[v].length()*10, yValue);
        text(words[v] +" ("+words[v].length()+")", words[v].length()*11, yValue+4);
    
        println (words[v]);
        println (words[v].length());
      }
    }
    
  • thank you for the code. i think this example explains very well what i mean. i spent a bit of time trying to understand as much as i could what you did. the red lines are representing the length of the different words, but i can't understand why the vertical lines don't reflect the same length. i mean, shouldn't they be where the red line ends? what i am trying to achieve with all this is to draw only the vertical lines after every word. i am feeling so obtuse right now for not getting there despite all the help you gave me sigh.

  • edited August 2015

    you might want to look a textWidth in the reference

    String[] words;
    static final int GAP = 20;
    
    void setup() {
      size(1600, 600);
      //String[] s = loadStrings("Stream of Consciousness #1.txt");
      String[] s = {
        "Stream of Consciousness 1 txt, hello, good day", "nice"
      };
      String entiretext = join(s, ",");
      words = split(entiretext, ",");
      //printArray(words);
      textSize(15);
    }
    
    void draw() {
      background(255);
    
      int len = words.length;
    
      for (int v = 0; v < len; v++) {
    
        // cut out space at beginning and end   
        words[v] = trim(words[v]); 
    
        // calculate the y value for that word 
        int yValue = v*GAP + 22;
    
        // red : show text at pos 0,yValue
        fill(255, 2, 2);
        text(words[v], 0, yValue);
        // green: vertical line   NEW  NEW  NEW
        stroke(0, 255, 0);
        float cw = textWidth( words[v] );
        line(cw, yValue-14, cw, yValue+14); 
    
        // black 
        // stroke(0); 
        // line(words[v].length()+ v*GAP + 0, 0, words[v].length()+ v*GAP + 0, height);
    
        // red 
        //  stroke(255, 2, 2); 
        //  fill(255, 2, 2);
        //    line(0, yValue, 
        //    words[v].length()*10, yValue);
        // text(words[v] +" ("+words[v].length()+")", words[v].length()*11, yValue+4);
    
        // println 
        println (words[v]);
        println (words[v].length());
      } // for
    } // func 
    //
    
  • edited August 2015

    I also have made the obeservation that it is vital for textWidth() to work to call textSize() before it (I have it in draw())

    remark

    please note that with modern fonts the graphical length of the word (given by textWidth()) is not really connected to the number of chars (which we were talking about up to now).

    This is because the graphical width of letters is not the same in modern ttf fonts: m is much wider then i etc.

    textWidth() takes care of that.

    when we need to make a table (columns of numbers) in an e-mail or so, we use the font Courier or Lucida Console, e.g., because they have a fixed size

    https://en.wikipedia.org/wiki/Typeface#Proportion

  • size (988, 300);
    textSize(28);
    
    char c = 'T';
    float cw = textWidth(c);
    text(c, 0, 40);
    line(cw, 0, cw, 50); 
    
    String s = "Tokyo ldkrfjw oiuertweru mmksdjf vnv";
    float sw = textWidth(s);
    text(s, 0, 85);
    line(sw, 50, sw, 100);
    
  • edited August 2015

    you wrote:

    i can't understand why the vertical lines don't reflect the same length. i mean, shouldn't they be where the red line ends?

    not really...

    look at the old code I wrote

    black line:

    stroke(0); 
    line(words[v].length()+ v*GAP + 32, 0, 
          words[v].length()+ v*GAP + 32, height);
    

    red line

    stroke(255, 2, 2); 
    int yValue = v*GAP + 22;
    fill(255, 2, 2);
    line(0, yValue, 
          words[v].length()*10, yValue);
    

    As you see, the black lines x-value is words[v].length()+ v*GAP + 32

    and the red line goes to a x-value of words[v].length()*10

    (actually imho it doesn't make much sense to use v*GAP in an x-value formula but here you go. I think it's more for y-value)

Sign In or Register to comment.