מלמולים טכנולוגיים

קוד פתוח, בלון נפוח

קבוצת דיוור חדשה: DevOps Israel

פורסמה על־ידי ozzyboy ב 16/08/2011

הודעה זו נכתבה במקור בוואטסאפ, אבל ראיתי לנכון לפרסם אותה גם כאן:

רציתי להזמין אתכם לקבוצה חדשה: DevOps-IL
הקבוצה מוקדשת לתנועת ה DevOps בארץ.
אני יודע שמלבד אנוכי, ישנם לא מעט אנשים גם בקהילת התכנה החופשית וגם מחוצה לה שמתעניינים בנושא וישמחו לקחת חלק בדיונים עליו.
הרעיון הוא להתחיל ברשימת תפוצה ואם אכן תהיה הענות – לארגן גם מפגשים והרצאות.

למי שלא מכיר או לא שמע, DevOps היא תנועה שקוראת לקרב בין תחום התשתיות והסיסטם לבין תחום פיתוח התוכנה.
הרעיון הוא שמפתחי תכנה יהנו מהיכרות מעמיקה עם התשתית עליה הקוד שהם כותבים רץ, ומהצד השני, אנשי תשתיות וסיסאדמינים יבינו יותר לעומק את צד הפיתוח ואת ההשלכות שלו על התשתית.
תחום זה מערב גם תהליך הפיתוח וגם את תהליך ה deployment (פריסה..?) וכן מעודד שימוש בכלים שמקלים על תהליכים אלו:
כלי ניהול קונפיגורציה כגון Puppet ו- Chef
כלי continuous integration כגון Jenkins (לשעבר, Hudson)
וברמה הבסיסית יותר – כלי ניהול גרסאות (Git, SVN וכו')
ומתודולגיית פיתוח (agile programming, test driven developement) והכלים שעוזרים למתודולוגיות אלו להתקיים.

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

פורסם ב DevOps, לינוקס, פיתוח, תוכנה חופשית | לכתוב תגובה »

להתעדכן בחדשות משורת הפקודה

פורסמה על־ידי ozzyboy ב 30/12/2010

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

python -c "import urllib2; import xml.dom.minidom; print('\n'.join([ item.getElementsByTagName('title')[0].childNodes[0].nodeValue for item in xml.dom.minidom.parseString(urllib2.urlopen('http://www.ynet.co.il/Integration/StoryRss1854.xml').read()).getElementsByTagName('item') ]))"

עריכה: גרסא מקוצרת ואלגנטית יותר (תודה מאיר):

python -c "import urllib2; from xml.etree.ElementTree import parse; print('\n'.join([title.text for title in parse(urllib2.urlopen('http://www.ynet.co.il/Integration/StoryRss1854.xml')).findall('/channel/item/title')]))"

והרי רשימת הכותרת מ RSS המבזקים של YNET.
ניתן לשנות את ה URL שיתאים לכל אתר אחר שמייצא RSS בצורה תקנית.
עצה קטנה: בדביאן ונגזרותיה, אם רוצים שעברית תציג כמו שצריך בטרמינל, מומלץ להשתמש ב mlterm.

פלט לדוגמא. הבלוג אינו אחראי לדיכאון העלול להגרם מקריאת הכותרות

פורסם ב אובונטו, באסה, דביאן, לינוקס, פייתון, תוכנה חופשית | 8 תגובות »

בדיקת שערי מט"ח באמצעות פייתון

פורסמה על־ידי ozzyboy ב 09/12/2010

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

הסקריפט רחוק מלהיות מושלם ובוחר שלא להתמודד כלל עם שגיאות אפשריות – אבל הוא עושה את העבודה ומשמש בעיקר לשם ההדגמה.

אם מישהו ימצא את זה שימושי, מה טוב.

#!/usr/bin/env python
import urllib2
from xml.dom import minidom as dom


def get_tag_str_content(xml_tag):
    for c in xml_tag.childNodes:
        if c.nodeType == c.TEXT_NODE:
            return c.nodeValue # Return the first text node found.
    return None


def get_rate_by_code(currency_code):
    # Fetch and parse the XML from the bank of israel
    response = urllib2.urlopen('http://www.bankisrael.gov.il/currency.xml')
    xml_doc = dom.parseString(response.read())
    
    # Search for the required currency
    for currency in xml_doc.getElementsByTagName('CURRENCY'):
        curr_elem = currency.getElementsByTagName('CURRENCYCODE')[0]
        curr = get_tag_str_content(curr_elem)
        if curr == currency_code:
            # Get the current rate, and convert it into a float 
            rate_elem = currency.getElementsByTagName('RATE')[0]
            return float(get_tag_str_content(rate_elem))
    
    return None # If the currency code is not found
    


if __name__ == '__main__':
    rate = get_rate_by_code('USD')
    print('the current rate of the US dollar is: %.3f nis' % (rate))
    

שבת שלום.

פורסם ב פייתון, תוכנה חופשית | 4 תגובות »

בניית web-services בפייתון, בקלות

פורסמה על־ידי ozzyboy ב 29/07/2010

פייתון מגיע עם שרת XML-RPC כחלק מהספריה הסטנדרטית שלו.
לאלו מכם שלא מכירים את XML-RPC – זהו פרוטוקול רשת , מבוסס XML שמאפשר להריץ פרוצדורות מרוחקות.
במילים אחרות, XML-RPC מאפשר לנו להריץ קוד על שרת מרוחק ולקבל חזרה את התוצאה.
זהו פרוטוקול יחסית פשוט לממשקי רשת, שממנו בסופו של דבר צמח הסטנדרט של SOAP.

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

לצורך ההסבר, בניתי שירות "ענן" (במרכאות כפולות ומכופלות) שמאפשר למשתמשים לקבל מסד נתונים על השרת, ולדבר עימו באמצעות XML-RPC.
כמובן, לא הייתי משתמש בקוד הזה בשביל שום דבר שאינו דוגמא מהסיבות הבאות:

1. אבטחה (לא קיימת כלל) – כל המידע עובר ברשת כטקסט ואינו מוצפן. אין שום מנגנון אימות משתמשים.
2. ביצועים (השרת הבסיסי משרת רק לקוח אחד בכל רגע נתון).
3. הקוד בקושי נבדק וסביר להניח שהרבה דברים לא יעבדו כמצופה.

אבל – בשביל ללמוד ולהבין כיצד להשתמש ב XML-RPC – הקוד הזה מושלם :)

אז נתחיל בצד השרת:

#!/usr/bin/env python

from SimpleXMLRPCServer import SimpleXMLRPCServer
import sqlite3


class SqliteServer(object):
    """
    A wrapper class form SQLite.
    used for registering XML-RPC methods.
    """
    def __init__(self, db_file):
        """
        start a connection.
        A DB file is mandatory (will be created if doesn't alread exist)
        """
        self.con = sqlite3.connect(db_file)
        self._c = self.con.cursor()
        
    
    def execute(self, query, params=None):
        """
        run an SQL statement with optional parameters.
        returns a pickleable result set.
        """
        results = []
        if params:
            self._c.execute(query, params)
        else:
            self._c.execute(query)
        for r in self._c:
            results.append(r)
        return results

    def commit(self):
        self.con.commit()
    
    def list_tables(self):
        """
        return a list of tables in the database, as an array
        """
        query = """SELECT name FROM sqlite_master
                    WHERE type='table'
                    ORDER BY name"""
        res = self.execute(query)
        tables = []
        for i in res:
            if len(i) > 0:
                tables.append(i[0])
        return tables


if __name__ == '__main__':
    # Init an SQLite wrapper pointing to a 'test.db' file
    backend = SqliteServer('test.db')
    
    # Start an XML-RPC server
    server =  SimpleXMLRPCServer(('localhost',8080), allow_none=True)
    
    # Register the methods from the wrapper class
    server.register_instance(backend)
    
    # Serve.
    server.serve_forever()

אז מה יש לנו כאן?
קודם כל, אנחנו מייבאים (import) מחלקה שנקראת SimpleXMLRPCServer, מתוך מודול בעל שם זהה.
זהו שרת ה XML-RPC הבסיסי שמגיע עם הפצת הפייתון. בנוסף אנחנו מייבאים את הספריה שמאפשרת לנו להשתמש ב SQLite, מסד הנתונים שלנו.

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

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

לאחר מכן, אנחנו מגדירים אובייקט שרת XML-RPC, שיאזין על הכתובת המקומית, בפורט מספר 8080.
רצוי לא להריץ את הקוד הזה על שום כתובת אחרת מלבד המקומית, מהסיבות הפורטו לעיל.

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

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

  • נהרוג אותה ידנית
  • נגרום איכשהו לשגיאה פאטאלית שתגרום לשרת ליפול.

וזהו. זה צד השרת.

צד הלקוח:

#!/usr/bin/env python
import xmlrpclib

if __name__ == '__main__':
    # Start an XML-RPC client 
    server = xmlrpclib.ServerProxy('http://localhost:8080')
    
    # Check if a table called 'students' exists
    if not 'students' in server.list_tables():
        # If not, create it.
        server.execute('create table students (fname text, lname text)')
        server.commit()
    
    # Insert a new student...
    server.execute('insert into students values (?, ?)', ('billy','bob'))
    server.commit()
    
    # Get all students
    resp = server.execute('select * from students')
    for i in resp:
        print(i)

כמו שאתם רואים, לא הרבה קוד.
התחלנו מלייבא את הספריה שמטפלת בXML-RPC.
לאחר מכן, הגדנו אובייקט proxy שמתחבר לשרת שלנו, ודרכו נוכל להריץ את הקוד המרוחק
לאחר מכן, נריץ את המתודה שמחזירה לנו את שמות הטבלאות הקיימות. אם טבלת הסטודנטים לא קיימת,
נריץ מתודה נוספת, שמקבלת קוד SQL, ולמעשה יוצרת את הטבלה

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

עוד על המודולים שתוארו כאן אפשר למצוא בתיעוד הרשמי הנהדר של פייתון.

פורסם ב פייתון, תוכנה חופשית | לכתוב תגובה »

פייתון ידידותי – IPython

פורסמה על־ידי ozzyboy ב 01/03/2010

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

למרות הפשטות הרבה (או אולי בגללה) עבודה מול הסביבה היתה תמיד חויה מעט מוגבלת. לפחות לאלו שמורגלים בסביבות טקסטואליות מתקדמות (למשל שורת הפקודה בלינוקס).

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

התקנה

ההתקנה של IPython יכולה להתבצע או דרך מנהל החבילות של מערכת ההפעלה (aptitude install ipython וכדומה), או אם אנחנו בתוך סביבה וירטואלית (בתוך virtualenv, עליו ארחיב בפעם אחרת), ניתן להתקין פשוט ע"י easy_install ipython או pip install ipython.

הפעלה

על מנת להפעיל את IPython, ניתן פשוט לכתוב ipython  בשורת הפקודה.

עבור אלו שעובדים עם django - סקריפט ה manage.py יודע לזהות לבד את קיומה של IPython, והרצת manage.py shell תריץ באופן אוטומטי את הסביבה.

יתרונות

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

למשל, אם נכתוב

import os
os.path.j<tab>

נקבל השלמה אוטומטית לפונקציה join שנמצאת בתוך os.path

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

בשביל לקבל עזרה על מודול מסויים, אפשר פשוט להקיש את שמו עם סימן שאלה בסוף:

In [1]: import os

In [2]: os?
Type:           module
Base Class:     <type 'module'>
String Form:    <module 'os' from '/home/oz/inter1/lib/python2.6/os.pyc'>
Namespace:      Interactive
File:           /home/oz/inter1/lib/python2.6/os.py
Docstring:
 OS routines for Mac, NT, or Posix depending on what system we're on.

 This exports:
 - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
 - os.path is one of the modules posixpath, or ntpath
 - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'
 - os.curdir is a string representing the current directory ('.' or ':')
 - os.pardir is a string representing the parent directory ('..' or '::')
 - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
 - os.extsep is the extension separator ('.' or '/')
 - os.altsep is the alternate pathname separator (None or '/')
 - os.pathsep is the component separator used in $PATH etc
 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
 - os.defpath is the default search path for executables
 - os.devnull is the file path of the null device ('/dev/null', etc.)

 Programs that import and use 'os' stand a better chance of being
 portable between different platforms.  Of course, they must then
 only use functions that are defined by all platforms (e.g., unlink
 and opendir), and leave all pathname manipulation to os.path
 (e.g., split and join).

In [3]:

ניתן לחזור על הפקודה, עם שני סימני שאלה בסוף, ולקבל עזרה מורחבת (כולל את קוד המקור של המודול המדובר).
דבר נוסף שמצאתי כמאד שימושי היא מערכת ה %magic.
זה בעצם סט של פקודות מובנות, כולן מתחילות באחוז ("%"), שמספקות המון קיצורי דרך שימושיים.
למשל %cd ולאחר מכן שם של ספריה, יעביר אותנו לספריה שציינו, או %edit שמאפשר לנו לערוך בעורך נורמלי קוד,
וכשנצא מהעורך, יורץ הקוד שערכנו. אופציה ממש חמודה שאהבתי היא %bg שמאפשר לנו להריץ פונקציה מסויימת ברקע:

In [1]: def count(up_to):
 ...:         counter = 0
 ...:         while counter < up_to:
 ...:                 counter += 1
 ...:

In [2]: %bg count(100000)
Starting job # 0 in a separate thread.

למעשה, נוצר thread חדש שמריץ את הפונקציה שלאחר bg.
הסבר על כל פקודות הmagic ניתן לקבל כך:

In [1]: %magic

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

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

משתמשים בipython בעצמכם? אשמח לשמוע טיפים שימושיים בתגובות :)

פורסם ב לינוקס, פייתון | 2 תגובות »

KDE 4.4 על נטבוק

פורסמה על־ידי ozzyboy ב 14/02/2010

הנטבוק שלי, שעבר הרבה (הרבה) התעללויות בשנה האחרונה, החליף שוב הפצה.
לאחר שדביאן, החזיקה מעמד קצת פחות מחודשיים (זה לא את, זה אני), החלטתי להחליף שוב.
והפעם: ארץ'. ארץ' היא אחת ההפצות החביבות עלי כבר זמן רב, והיא מותקנת לי על המחשב ה"רגיל". בימים האחרונים שוחררה KDE 4.4, וכיאה להפצה מתגלגלת, ארץ' הוסיפה את הגרסה החדשה למאגרים זמן קצר לאחר הודעת השחרור.
הרבה שמעתי על גרסא 4.4, ובמיוחד על מצב הנטבוק של פלזמה (מערכת ניהול שולחן העבודה של KDE 4).
בהיותי חובב גנום, תמיד ראיתי ב KDE כסביבה טובה, אבל טיפה מצועצעת.
החלטתי לראות מה חדש ולהתקין את ארץ' (מה שיתברר כחוויה נוחה מהמצופה על הנטבוק) + KDE בבגדיו החדשים.

ההתקנה עצמה של ארץ' נעשתה כהתקנת רשת. מורידים ISO קטן שמכיל סביבה בסיסית שמאפשרת להתחיל את ההתקנה, וכל החבילות נמשכות ישירות מאתרי המראה. כך מקבלים מערכת מעודכנת כבר מההתקנה. ההתקנה הטקסטואלית עברה בצורה די קלה. ה LIVE CD הקטן הכיל כבר תמיכה בכרטיס הרשת האלחוטי, ולאחר דקות מעטות, חבילות הבסיס כבר הורדו מאתר המראה של המקור. המערכת עלתה במלוא תפארתה הטקסטואלית, ולאחר הגדרה קצרה של X, alsa ועוד מספר שירותי מערכת חשובים, התפנתי להתקנה של KDE.
רשמתי בטרמינל

pacman -S kde

וחיכיתי. 540MB של חבילות הורדו והותקנו מהאינטרנט. KDM הוסף לרשימת ה DAEMONS בקובץ ה rc.conf, ולאחר איתחול עלה שולחן העבודה החדש.
אני חייב לומר שהחבר'ה שם ב KDE עשו עבודה ממש טובה. ומבחינה גרפית הסביבה נראית מאד מאד מרשימה, גם על תצוגה מוגבלת כמו זאת של הנטבוק.
את מצב הנטבוק של פלזמה, דווקא לא אהבתי. לא מצאתי אותה יותר נוחה או יעילה על מסך קטן מאשר שולחן עבודה "רגיל". כך גם הרגשתי כשאובונטו הוציאו את גרסאת ה UNR שלהם.

מצב הנטבוק של פלזמה. בסוף בחרתי לא להשתמש בו

על מנת ליצור אחידות בין הישומים (אני עדיין משתמש בהרבה ישומים GTKים), התקנתי את החבילות qtcurve-gtk2 ו- qtcurve-kde4
שמאפשרות לישומי GTK להשתמש בערכות הנושא של QT.

KDE 4.4 על הנטבוק

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

Akregator, Konqueror ו - Amarok בחלון אחד

מעבר לכך, המערכת מרגישה קלה יותר ממה שזכרתי את KDE 4 (אולי זה לזכותו של ארץ' ולא KDE). אבל בכל מקרה, אין ספק ש KDE היא לא בדיוק הסביבה הנבחרת עבור מחשב כזה. בפועל, למרות שנראה כאילו המפתחים באמת השקיעו תשומת לב רבה בהתאמת הסביבה למחשבים חלשים (ממשק מיוחד לנטבוקים) מבחינת ביצועים כנראה שבכל זאת עדיף שולחן עבודה קל יותר כמו XFCE, openbox או E17. אבל – בינתיים המחשב הקטן איכשהו "סוחב" את KDE, אז נראה לי שאשאר איתו לפחות לתקופה הקרובה.

פורסם ב ארץ', לינוקס, נטבוק | 2 תגובות »

התנהגויות מוזרות בפייתון – חלק א'

פורסמה על־ידי ozzyboy ב 20/01/2010

באנגלית יש דבר שנקרא gotcha, או לעיתים pitfall. לצערי לא מצאתי מילה מקבילה להן בעברית, אך המשמעות היא – מקומות שבהם אתה עושה משהו, ומצפה שיקרה תרחיש מסויים, אך למעשה מתרחש משהו אחר במקום.

מושגים אלו נפוצים מאד בעיקר כשמדברים על שפות תכנות.

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

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

(לינקים למאמרים המקוריים יצורפו בסוף).

אז לדוגמא הראשונה:

>>> a = 200
>>> b = 200
>>> a is b
True
>>> a = 300
>>> b = 300
>>> a is b
False

מה בעצם קרה כאן?

ביצענו השמה של ערך אינטי (יענו, מלשון integer), בשני משתנים. a ו – b. המשתנים הללו, כמו כל שאר המשתנים בפייתון, הם אובייקטים.

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

בבדיקה הראשונה, לכל אובייקט מזהה משלו, ולכן הבדיקה מחזירה ערך שלילי.

אבל בבדיקה השניה, הערך הוא זהה, מה שאומר ש a ו – b הם למעשה אותו אוביקט! אבל מה השתנה?

אז מסתבר, שבאימפלמנטציה הנפוצה של פייתון, הלוא היא CPython, מתבצע caching של intים נפוצים (למעשה, בין -5 ל 256)

למטרות ביצועים, ולכן כל משתנה אינטי בטווח הנ"ל יקבל תמיד את אותו האובייקט.

אגב, בדקתי את ההתנהגות ב Jython, שהיא אימפלמנטציה לפייתון שכתובה ב Java, ושם הדבר קורה בטווח של -100 עד 899. (גרסא קצת מיושנת , 2.2.1)

התנהגות מוזרה נוספת:

>>> for i in range(20):
...     print "*",
...
* * * * * * * * * * * * * * * * * * * *

מי שקצת מכיר פייתון, יודע שהפקודה print מוסיפה לאחר המחרוזת גם תו ירידת שורה (n\). אבל במקרה הזה, אין ירידת שורה, אלא יש רווח במקום. למה? מסתבר שאם שמים את התו "," (יעני, פסיק) אחרי print – לא יודפס תו ירידת השורה.

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

התנהגות מוזרה נוספת:

>>> a = 0.1
>>> a
0.10000000000000001

למה פייתון הוסיף 0.00000000000000001 למספר שלי??? אתם בטח שואלים בזעם.

אז התשובה הפשוטה היא, שפייתון, כמו שפות אחרות, שומר מספרים בבסיס ספירה 2 (הלוא הוא הבסיס הבינארי – ספרות 0 ו- 1), בעוד אנחנו בני התמותה נוטים להשתמש דווקא בבסיס ספירה דצימלי (יעני, ספרות 0-9).

כמו שיש מספרים שלא ניתן לייצג בדיוק של 100% בבסיס דצימלי (למשל – שליש הופך ל 0.3333, עד לרמת דיוק אין סופית), כך גם בבסיס הבינארי.

במקרה הזה, הפונקציה repr שמופעלת על האובייקט שלנו (float) מעגלת את המספר לעד 17 ספרות לאחר הנקודה העשרונית – וזה הערך שמתקבל.

עוד מוזרויות – בחלק הבא.

לינקים:

Python Gotchas

When Pythons Attack

10 Python pitfalls

פורסם ב פייתון | לכתוב תגובה »

דביאן על MSI Wind U100 (או נטבוקים באופן כללי)

פורסמה על־ידי ozzyboy ב 31/12/2009

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

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

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

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

ההפצה, הלא היא דביאן (יש היאמרו – הישנה והטובה) – הפתיעה הפעם לטובה.

בחרתי להתקין את גרסאת ה – testing, הקרויה בשם הקוד squeeze.

החלטתי לא להתקין את הגרסא היציבה, בגלל גרסאת הקרנל (בטסטינג הקרנל מגיע בגרסא 2.6.30 שכבר כולל תמיכה "בילט-אין" לכרטיס הרשת האלחוטי של ה u100), וכן בגלל גרסאת גנום – 2.28 לעומת 2.22 המעט מיושנת של lenny.

את ההתקנה ביצעתי מדיסק שהכינותי מראש, שנתחב לתוך כונן DVD חיצוני בחיבור USB, שכן לנטבוק שלי, כמו לבעצם כל הנטבוקים שהם – אין כונן CD מובנה.

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

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

החלטתי להשאר עם גנום, למרות שעל הנייר LXDE או XFCE אמורים לספק ממשק קל יותר, אבל משום מה הם תמיד נראים לי לא מלוטשים.

שולחן העבודה החדש

מבחינת קונפיגורציה לא היה לי הרבה מה לעשות, שכן כל החומרה עבדה "מהקופסא", כולל כרטיס הרשת והמצלמה . עדכון והוספת מאגרים (contrib ו- non-free – וכן המאגר של debian-multimedia.org).

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

רק למה האייקון של iceweasel כזה מכוער?

פורסם ב אובונטו, דביאן, לינוקס, נטבוק | תגובה אחת »

מדריך: איך לגרום לאובונטו להראות בדיוק כמו XP

פורסמה על־ידי ozzyboy ב 27/12/2009

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

ראיתי  במהלך השנים מספיק הפצות בנוסח Lindows (ששמה שונה ל Linspire, שנקנתה על ידי Xandros), ויש אפילו הפצה שנקראת Linux XP, אבל למה לקחת שולחן עבודה גנומי ונאה ולאנוס עליו ממשק משתמש שגם לפני כמעט 9  שנים (שזה פחות או יותר מתי ש XP יצאה לשוק) לא היה מושך במיוחד?

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

פורסם ב אובונטו, לינוקס, צחוקים | לכתוב תגובה »

דרך מגניבה לשלוט על HTPC

פורסמה על־ידי ozzyboy ב 22/12/2009

HTPC, או מחשב מדיה אם תרצו, הוא מחשב כמו כל מחשב.

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

השליטה עליו, יכולה להתבצע בכמה דרכים:

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

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

השקעתי וקניתי עכבר ומקלדת שאיכשהו יראו סביר בסלון (למעוניינים: Logitech LX710), ורוב הזמן הם באמת עשו את העבודה

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

אז איזה עוד פתרון יש? בהמהלך אחד מטיולי חסרי הפשר ברחבי האינטרנט, נתקלתי בדבר הזה:

המכשיר

לא, זה לא בלאקברי עם מסך שבור, אלא קומבינציה של מקלדת זעירה וטאץ'-פאד אלחוטיים.

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

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

טוב, לא בדיוק, יש גם חסרונות (אין מקש shift, רק caps lock, מה שעלול להקשות על מי שרגיל להחליף שפה עם alt + shift), המקדלת היא רק באנגלית (גם עלול להקשות על המקלידים בעברית..) ובאופן כללי הפלסטיקה של המכשיר מרגישה די זולה ושברירית.

אבל בשבילי, ובשביל ה HTPC שלי – זה הפתרון הכי נוח לבינתיים.

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

פורסם ב HTPC, אובונטו, לינוקס | לכתוב תגובה »

 
Follow

Get every new post delivered to your Inbox.