28 בפבר׳ 2009

TwitGraph



הרבה זמן מטרידה אותי השאלה איך מקבלים פידבק ממשתמשים באופן יעיל? איך מודדים הצלחה של מוצר או הצלחה של קמפיין? ברור שלא אני הראשון ששואל את השאלות הללו אבל אני שמח לבשר שהתחלתי לפתור את הבעייה הקטנה והנקודתית שלי ואני חולק כאן את הפתרון.

אז נתחיל עם הגדרת הבעיה: אני עובד על מוצר שיש לו הרבה מאוד משתמשים וכל חיפוש בגוגל, טוויטר ובבלוגים מניב מאות תוצאות וזה מאוד מעניין לקרוא אותן ולהבין יותר טוב מה המשתמשים שלנו חושבים עלינו. מצאתי שהפידבק בטוויטר הוא מאוד יעיל ואני משתמש בו המון כדי לשמוע תלונות, שבחים, להכיר סרטים חדשים שמשתמשים בפיצ'ר וכו'. לעתים יש כמה מאות טוויטים בכל יום, אז חיפשתי דרך לכמת את הפידבק בטוויטר, כלומר לראות באופן ויזואלי כמה טוויטים יש עלינו בכל יום ואף לראות כמה חיוביים וכמה שליליים מביניהם.

תחילה חיפשתי אפליקציה שתספק לי את התשובה הזו, אך משלא מצאתי, החלטטי לכתוב אחת משלי. קראתי לה טוויט-גרפ והנה היא כאן.





לקח לי פלוס מינוס שני לילות לכתוב אותה והיא ממש רק בחיתולים (יש רשימה ארוכה של TODO כאן) אבל אני כבר יכול לעשות בה שימוש אפקטיבי. רציתי לספר קצת על אופן הפיתוח שלה.

כמו שכבר הזכרתי, הצורך נבע מצורך אישי שלי לכמת ולראות בצורה גרפית מה העולם חושב, או יותר ספציפית, מה משתמשי טוויטר חושבים עלינו ומשלא מצאתי כלי מתאים שמחתי שיש לי הזדמנות לעשות משהו מועיל ולא רק לצורך התרגול, אלא ממש משהו שימושי (שדרך אגב, בחוג חברים מצומצם כבר עושים בו שימוש נוסף).

התחלתי לחפור ב Search API של טוויטר עד אשר מצאתי את מבוקשי. החלטטי שאני אשתמש ב App Engine, פלטפורמת אפליקציות הווב של גוגל גם בגלל שזה חינם ופשוט וגם בגלל שרציתי להעמיק את נסיוני בפלטפורמה ובפייטון והתחלתי בעבודה.



אז איך זה עובד? (טכני. וארוך...)

היה מעניין לעבוד על האפליקציה ולמדתי מספר דברים אז החלטתי לחלוק את נסיוני כאן. כל הקוד פתוח, ניתן למצוא אותו כאן ואני אשמח לקבל עזרה (ראו את רשימת ה TODO שלי)



ה API של טוויטר מאפשר לעשות חיפוש של search term כלשהו, למשל youtube annotations, כמו גם חיפושים מורכבים יותר כגון "כל הטוויטים שנשלחו אלי" - to:rantav או "כל הטוויטים שאני שלחתי ויש בהם יוטיוב" from:rantav youtube

בנוסף ה API תומך באופרטורים :) ו :( כלומר פילטור התוצאות לפי תוצאות שמחות או תוצאות עצובות. זה נעשה ע"י ניתוח "גוון הטקסט" של הטוויט והבנה האם הוא חיובי או שלילי, אבל לטעמי לא נעשה בצורה טובה ולכן אני אנסה לממש אותו בעצמי לכשיהיו לי כמה לילות פנויים.

ה API גם תומך לא רק בפורמט הקומפקטי של json כי אם גם ב jsonp, מה שמאפשר לי לפנות מהדפדפן ישירות אל טוויטר ללא צורך לעבור דרך השרת. זה גם נחמד יותר לביצועים וזה גם עדיף משיקולי scalability. הנה כמה שאילתות לדוגמא. אני משתמש ב curl כדי להריץ את השאילתה מה- command line אבל מי שאין לו curl מותקן יכול להשתמש ב wget או דומיו.




$ curl http://search.twitter.com/search.json?q=video+annotations



{"results":[{"text":"Anyone noticed how I've used annotations in my yesterday's http:\/\/sendme.to\/genov0003 video? I think it really helps ppl keep up with speech", ...},..more results here...],

"since_id":0, "max_id":1262171803, "refresh_url":"?since_id=1262171803&q=video+annotations", "results_per_page":15, "next_page":"?page=2&max_id=1262171803q=video+annotations", "completed_in":0.026702,"page":1, "query":"video+annotations"}




ניתן לראות שיש כאן מערך של תוצאות:



{"results":[{...},..more results here...],...}


ועוד metadata על השאילתא עצמה, כגון איזה עמוד זה, כמה תוצאות, והחשוב מכל, איך מקבלים את העמוד הבא:



"next_page":"?page=2&max_id=1262171803&q=video+annotations"


באמצעות ה next_page אני מביא את העמוד הבא והבא עד שאין יותר תוצאות.

אבל כמובן שמספר התוצאות יכול להיות אינסופי, אז צריך להחיל מגבלה של תאריך התחלה ותאריך סוף, ולשם כך גם כן יש תמיכה ב API. הנה שאילתה לדוגמא:



curl "http://search.twitter.com/search.json?&q=youtube%20annotations%20
since:2009-01-31%20until:2009-02-01"





כעת, אחרי שכל התוצאות הגיעו (ע"י קריאות מרובות) אני עושה להן אגרגציה לפי תאריך ואז מציג אותן בגרף.

החלק של ציור הגרף הוא למעשה הקל ביותר כיוון שאני משתמש ב Google Visualization API שהוא די פשוט לשימוש. יוצרים DataTable, שהיא כמו מערך דו-מימדי, ממלאים אותה ואומרים לגרף לצייר. הנה הקוד של הציור:



SearchMaster.prototype.drawGraph = function(dates) {
        // Create and populate the data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Date');
        data.addColumn('number', 'All');
        data.addColumn('number', 'Happy');
        data.addColumn('number', 'Sad');
        data.addRows(dates.length);
        for (var i = 0; i < dates.length; ++i) {
                data.setCell(i, 0, dates[i].date);
                data.setCell(i, 1, dates[i].getAll());
                data.setCell(i, 2, dates[i].getHappy());
                data.setCell(i, 3, dates[i].getSad());
        }
      
        // Create and draw the visualization.
        $('graph').innerHTML = '';
        new google.visualization.LineChart($('graph')).
            draw(data, null);  
}




אז יש עוד כמה חלקים שלא פירטטי לגביהם, אחד זה איך יודעים כמה טוויטים חיוביים יש וכמה שליליים ושתיים, מה זה jsonp ואיך השתמשתי בו.



לגבי החיוביים והשליליים, בעצם על כל שאילתה של המשתמש אני שולח לטוויטר שלוש שאילתות: אחת נייטרלית, אחת חיובית ואחת שלילית. אם למשל השאילתה היא from:rantav אז למעשה נשלחות במקביל השאילתות הבאות:



from:rantav

from:rantav :)

from:rantav :(



וכאשר שלושתן חוזרות במלואן (כלומר כולל בקשות חוזרות עד שיש את כל הטוויטים בטווח התאריכים), רק אז אני מציג את הגרף.

זה לא מעט בזבזני כיוון שאני תמיד שולח לפחות שלוש שאילתות על כל אחת של המשתמש, ואף גרוע מזה, סיווג התוצאות הוא לא משהו בכלל. אבל בתור התחלה זה סביר הייתי אומר. אני רוצה לשפר את זה בהזדמנות הראשונה שתהיה לי.



בקשר ל jsonp, זו טכניקה לשליחת בקשות json בין דומיינים שונים ולשמחתי טוויטר תומך בה. למעשה כל הקוד שמממש את מה שמתואר למעלה כתוב ב javascript ורץ על הדפדפן, לא על השרת. מה שמרוויחים מזה זה שיפור ביצועים (ברוב המקרים) אבל חשוב יותר, אי-חסימה. מה זה אי-חסימה? טוויטר מגביל את מספר הבקשות שכל אחד יכול לבצע בדקה אז ככה שאם כל הבקשות של כל המשתמשים היו עוברות השרת אז מהר מאות הייתי מגיע למגבלה שלי. ככה, כאשר כל אחד שולח את הבקשות שלו ישירות לטוויטר אם הוא יגיע לחסימה, רק הוא ייחסם וגם יקח לו הרבה זמן עד שהוא ייחסם.

אז מה רע ב json? למה צריך להוסיף לו גם p? הסיבה היא שכאשר שולחים בקשה בין שני דומיינים שונים (דומיין המקור הוא twitgraph.appspot.com ודומיין היעד הוא search.twitter.com) אז יש מגבלת אבטחה שהדפדפן אוכף ובאופן כללי לא ניתן לשלוח בקשות XmlHttp בין שני דומיינים. גם שימוש ב iframe לא עוזר. אבל מה כן - ניתן להוסיף סקריפטים מכל מקום ומכל דומיין וברגע שמוסיפים סקריפט לחלק של ה head אז הדפדפן יריץ אותו, אפילו אם התוספת היא כבר זמן רב אחרי הטעינהֿ. התרגיל הוא כזה: במקום לשלוח בקשת XmlHttp מוסיפים סקריפט לדף והפרמטרים של הסקריפט הם השאילתה. הסקריפט הוא בעצם דינמי ונוצר על השרת בזמן הבקשה. מה שהסקריפט מכיל הוא קוד של javascript שבו פשוט קריאה לפונקציה בדף עם התוצאות של השאילתה. אז ברגע שהסקריפט חוזר הפונקציה לקראת ומקבלת את התשובה לשאילתה.

ויפה דוגמא אחת קודם:


$ curl "http://search.twitter.com/search.json?q=video+annotations&callback=myCallback"


myCallback({"results":[...}],...});


myCallback זו פונקציה על הדף שמקבלת את תוצאות השאילתא ברגע שהן מגיעות.

להלן הקוד שקורא ל jsonp ובעצם מוסיף קטע סקריפט באופן דינמי:


function jsonp(url, callbackName) {                
        url += '&callback=' + callbackName;
        var script = document.createElement("script");        
        script.setAttribute("src", url);
        script.setAttribute("type", "text/javascript");                
        document.body.appendChild(script);
}




אז בגדול אלו הדברים המעניינים. יש עוד הרבה קוד וכמו שציינתי הוא נמצא כאן ואם יש מעוניינים להצטרף למקצי השיפורים נא להשמיט כאן שורה (drop a line) או בטוויטר שלי rantav כי יש לי כבר הרבה מאוד רעיונות לשיפור.



פודקאסט מספר 8 - Debugger - ידידו הטוב של המפתח... או שלא?

בפודקאסט מספר 8 של רוורס עם פלטפורמה אירחנו בפעם השניה את יוסי גיל והפעם... הפתעה - איסור מוחלט על שימוש ב-DEBUGGER.
  • האם אפשר לחיות בלי Debuggers?
  • שיטת ה"דלות" - או -DALUT (תיעוד, התראות, לוגים, ובדיקות יחידה).
  • "קודם כל לחשוב" - טוב זה תמיד נכון.
  • String- בירושלמית זה "סדרית".
  • "לדבג" זה יותר מהיר או איטי?
  • Debugger- העיניים שמראות לנו את מקרי הקצה.
  • אספקטים של חיזוי זמן פיתוח.
  • חוויותיו של יוסי בשוחות הקוד.
  • לוגים - פסטיבל מספרי סיפורים של מה שקורה לקוד שלך בזמן אמת, אצל הלקוח.
  • MULTI-THREADING - דיבאגגינד בסביבה מרובת פתילים, או חוטים.
  • קריאת קוד מעמיקה של כמה אנשים יכולה למצוא באגים ממש קשים.
  • האם יש מקרים לגיטימיים להשתמש ב-Debugger?
  • חיפוש באגים כמו שמחפשים אריה במדבר.
  • Code Review - כלי נוסף לשפר איכות קוד ולעלות על באגים.
גלשנו בזמן כי היה לנו מאוד מעניין - אז קבלו את התנצלותנו על כך.
תודה על התגובות ואנחנו נשמח לקבל עוד תגובות. תודה גם לאריק על הפוסט.
הקובץ של הפרק הזה כאן
להשתמע.

19 בפבר׳ 2009

פודקאסט מספר 7 של רוורס עם פלטפורמה ראה אור זה עתה.
הפעם אספנו קצת גבב דברים על חידושי קוד.
  • ניצלנו את ההזדמנות לספר קצת על הפודקאסט שלנו (למי שלא מכיר)
  • הכל התחיל בהערה של דוד על הפודקאסט הקודם
  • התייחסנו בעיקר למאמר תרגום לפוסט של יואל ספולסקי.
  • דוגמאות לשכתוב קוד בעברנו או איך מעבירים אפליקציה - מווינייט - דרך פרל - ל ג'אווה.
  • מתי אפליקציה מתקרבת ל"קיר" ודורשת שכתוב.
  • תכנה מזדקנת? עוד נדבר על זה בהמשך.
  • "לזרוק ולכתוב מחדש" - למה??? זה עוד עובד!
  • תוכנות הביטוח כתובות ב- קובול - שנאמר... "קוד זה לא חברת ביטוח"
  • פרל וטוויטר - קוריוז.
  • פיתוח מונחה בדיקות - יכול (או לא) לעזור בשכתוב קוד.
נתנו את הסיומת הרגילה.
את הקובץ ניתן למצוא גם כאן
שבוע טוב והאזנה נעימה.... צ'או.

16 בפבר׳ 2009

דרושים לפודקאסט: מומחי ווב

אני ואורי רוצים לשדר פרק של הפודקאסט-תכנה שלנו, רוורסים, על פלטפורמות ווב. כל השמות הגדולים וההיסטוריים יהיו שם, החל מ פרל ו סי-גי-איי, דרך סטרטס וכלה ברובי הקטר המאושר ודג'נגו.
אבל אנחנו לא רוצים לעשות את זה לבד, אנחנו רוצים לשתף אתכם בשידור.
אז אם אתם מומחים לאחת מהפלטפורמות שבשימוש היום או שהיו פעם, או כל טכנולוגיית ווב אחרת שקשורה אז אתם מוזמנים לקחת חלק בשידור.
  • RoR
  • Django
  • Struts
  • ASP
  • ASP.NET
  • JSF
  • Hibernate
  • webwork
  • and more...

אנחנו רוצים לערוך מעין פאנל של מומחים שבו כל אחד יכול להציג את אחת מהפלטפורמות או אחת מהטכנולוגיות אותה הוא מכיר היטב ולהשוות ביניהן ולהבין מה היתרונות של כל אחת. אז אם אתם מומחים, או סתם מכירים די טוב, אתם ממש מוזמנים להשתתף.
את ההקלטה נעשה דרך שיחת ועידה של סקייפ, ככה שלא צריך לסוע הרבה. המועד טרם נקבע, אז מי שיהיה ראשון תהיה לו הכי הרבה השפעה. בגדול מדובר על מהלך השבועות הקרובים.

מי שמעוניין מוזמן לפנות אלי: רן [את] רוורסים.קום או אל אורי [את] רוורסים.קום
נשתמע

10 בפבר׳ 2009

פודקאסט מספר 6 של רוורס עם פלטפורמה

בפודקאסט מספר 6 דיברנו על עקרונות תכנה ויצירתיות של מתכנתים.
אירחנו את יוסי גיל - מרצה בטכניון וגוגלר אשר רוב הסטודנטים לתכנה בטכניון בוודאי מכירים בתור מרצה מחונן ובעל עניין רב.
יוסי חלק איתנו את עקרונות פיתוח התכנה שליקט והתמקדנו בעיקר בעקרון היצירתיות ומה שמסביבה.
  • מתכנתים הם בד"כ יצירתיים?!? - האמנם? מה טוב ומה רע בכך?
  • גוגלרים מעדיפים צפרדעים.
  • יצירתיות - כדי לבנות את מה שאתה צריך לא מה שאתה רוצה.
  • איך לובשים חולצות - עם או בלי כפתורים.
  • מתכנתים שעושים פיצ'רים במוצר רק כי אפשר.
  • מינימליזם - "פחות זה יותר". (פחות או יותר)
  • תרוצים שמתכנתים משתמשים בהם: כי זה יותר יפה, כי זה יותר קריא, כי זה "יותר מונחה עצמים..."
  • לגו או חימר? מה יותר אומנותי?
  • מתכנתים והערכות זמנים - "כי ככה".
  • עקרון השטויות - טאוטולוגיה או טעות-או-לוגיה.
  • יוסי סקר את שאר העקרונות כהכנה לשידורים העתידיים.
הקובץ נמצא כאן.
ואם אמרתי בשידור שהפיצ'ר הנסיוני של אאוטבריין לא עובד לי אז אני מתנצל - טעות שלי, הוא עובד פגז.

זהו - אנחנו מזמינים אתכם - אם יש לכם רעיונות לנושאים - תכתבו לנו.



8 בפבר׳ 2009

מילים אחרונות של מתכנתים


לא מזמן נתקלתי בשאלה "מה היו מילותיו האחרונות של מתכנת בשפה X" באתר stackoverflow וכיוון שכל כך נהנתי לקרוא את התשובות החלטתי למחזר כאן. ובכן:

מה יהיו מילותיו האחרונות של מתכנת C

main() { printf("goodbye, world"); }
מה יהיו מילותיו האחרונות של מתכנת Java

try{ ... }catch(Exception ignore){ //This won't happen }


מה יהיו מילותיו האחרונות של מתכנת perl
אני לא צריך לכתוב תעוד. הקוד כל כך יפה ומפורמט למופת שפשוט אפשר לקרוא אותו אחר כך

מה יהיו מילותיו האחרונות של מתכנת lisp
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

מה יהיו מילותיו האחרונות של מתכנת PHP
*/

מה יהיו מילותיו האחרונות של מתכנת python שמשתמש ב vi
:%retab!


מה יהיו מילותיו האחרונות של מתכנת bash
rm -rf /

מה יהיו מילותיו האחרונות של מתכנת כלשהו
אצלי על המחשב זה עבד!


5 בפבר׳ 2009

פודקאסט מספר 5 של רוורס עם פלטפורמה

ככה בין המילואים הצלחנו להשחיל הקלטת פודקאסט אחת של רוורס עם פלטפורמה. קצת הארכנו והסליחה עם כל מי שממתין בחניה לסוף הפרק :)
השבוע נושא שקרוב לליבנו - ווידג'טים וגאדג'טים.
  • דיברנו על דפי בית אישיים כביתם הראשון של הגאדג'טים.
  • מיהם שרותי השרת של ה"חפיצים".
  • אורי סיפר על הווידג'ט של אאוטבריין.
  • מה לווידג'טים ולתפוצה ברשת?
  • SaaS, SOA הארכיטקטורה שמאחור.
  • ווידג'טים ואבטחה.
  • סקרנו את הטכנולוגיות סקריפטים פלאש AJAX וכו'.
  • עבודה בין אתרים - מה הבעיה ואיך פותרים.
  • JSON ואיך הוא עוזר לנו לפתור את הבעיה.
  • "האנשים בבסיסם הם טובים" - לא לפחד מווידג'טים.
  • "ווידג'טים מנומסים" - איך אאוטבריין שומרים על זה בקנאות.
  • ברגע האחרון נכנס סיפור קצר על prototype.js .
כתבו לנו הערות והצעות לסדר והכי חשוב לתכנים שאתם רוצים שנדבר עליהם.
קובץ השמע נמצא כאן.
להתראות.