วันพุธที่ 8 มกราคม พ.ศ. 2557

Work 1 Resource Tracking - Update 3

Resource Tracking - Account Statement

1.แก้ไขไฟล์ Readme.txt ที่สร้างไว้ตอนแรกเปลี่ยนไปใช้เป็น Readme.rst ซึ่งเป็น format แบบ reStructuredText ซึ่งเมื่อ Upload Repositories แล้วจะแสดงข้อความในไฟล์ Readme.rst พร้อมจัดรูปแบบการแสดงผลตามที่เขียนไว้ในไฟล์ ซึ่งตอนที่ใช้ Readme.txt ก็จะแสดงเหมือนกันแต่จะไม่มีการจัดรูปแบบการแสดงผลซึ่งจะทำให้อ่านยากหาก Readme ของเรานั้นมีข้อมูลเยอะๆ

2.เพิ่ม templatestags filters เข้ามาเพื่อใช้ใน Templates สำหรับแสดงหน้า View Asset ที่มี filters ในรูปแบบต่างๆเช่น แสดงเฉพาะวันที่ , เดือน , ปี เป็นต้น โดยใน Templatetags นั้นได้ import API date , timedelta จาก datetime และ timezone จาก django.utils

ภาพตัวอย่างหน้า View Asset ที่เพิ่ม templatetags filters


 ภาพตัวอย่างหลังจาก commit Readme.rst ไปยังเว็บ http://bitbucket.org/


Read more ...

วันจันทร์ที่ 6 มกราคม พ.ศ. 2557

Work 1 Resource Tracking - Update 2

Resource Tracking - Account Statement

1.เพิ่มหัวข้อ Description เข้าไปใน Models แล้วเพิ่มช่องสำหรับรับค่า Description ในหน้า Add Income และ Add Expenses เพิ่มการแสดงผลของ Description ใน View Asset
2.เขียน Test สำหรับหน้าที่ใช้ในการแสดงผลทุกหน้า ที่มี ณ ปัจจุบัน

3.สร้างหน้าสำหรับการสร้าง Profile ขึ้นมาชื่อ Create Account

4.สร้างหน้าสำหรับการลบ Profile ออกชื่อ Delete Account

5.จากเดิมในหน้า Menu จะมีเมนู Edit income & expenses ทำการเปลี่ยนเมนูนี้ออก แล้วใส่ Delete Account เข้าไปแทน

6.ในหน้า Index ของ App Account_Statement เพิ่มเมนู Create Account เข้าไป

7.ปรับปรุง Templates ในการแสดงผลเพื่อให้ดูเป็นระเบียบและเรียบร้อยมากขึ้น

ภาพตัวอย่างหน้า Add Income และ Add Expenses ที่ปรับปรุงใหม่



ภาพตัวอย่างหน้า View Asset ที่ปรับปรุงใหม่


ภาพตัวอย่างหน้า Delete Account ที่สร้างขึ้นมาใหม่


ภาพตัวอย่างหน้า Create Account ที่สร้างขึ้นมาใหม่


ภาพหน้า Menu ที่แก้ไขล่าสุด


Read more ...

วันอาทิตย์ที่ 5 มกราคม พ.ศ. 2557

Work 1 Resource Tracking - Problem OperationalError with Solution

Problem OperationalError with Solution

    หลังจากที่เราทำการแก้ไข Models นั้นหลายๆคนคงต้องเจอปัญหา OperationalError พร้อมกับบอกว่า ไม่มี Field XXX ใน Table กันบ้างมาไม่มากก็น้อยโดยปัญหานี้เกิดจากเวลาที่เราให้ตัว Django syncdb แต่ตัว syncdb นั้นไม่ยอมแก้ไข table ให้ทำให้เกิดปัญหาดังกล่างขึ้น ซึ่งวิธีที่ผมเคยใช้แก้ปัญหานั้นคือการลบ db.sqlite3 แล้วสร้างขึ้นใหม่แต่นั่นทำให้ Data ทั้งหมดในนั้นต้องหายไปด้วย ดังนั้นวันนี้ผมจึงขอเสนอวิธีการแก้ไขปัญหาโดยที่ Data ของเรายังอยู่ครบเหมือนเดิมกันครับ

1.ดาวโหลด SQLite database browser ซึ่งเป็นโปรแกรมแบบ Open source หาโหลดได้จาก Ubuntu Software Center ที่มีมากับ OS Ubuntu ได้เลยครับ


โดยโปรแกรมที่เราโหลดตัวนี้สามารถเปิด db.sqlite3 ของเรามาทำการแก้ไขแบบ Manual ได้เลย

2.เปิด Terminal จากนั้น cd ไปยัง Directory โปรเจค Django ของตนเองจากนั้นพิม
python manage.py sql "Appname"
 โดย "Appname" นั้นเป็นชื่อ App ที่แต่ละคนตั้งเองครับจะได้ดังตัวอย่างนี้


ให้เปิด Terminal หน้านี้ทิ้งไว้ก่อนจะนำไปใช้ในลำดับถัดไป

3.เปิดโปรแกรม SQLite database browser ที่เราโหลดมา จากนั้นเปิดไฟล์ db.sqlite3 ของเราที่มีปัญหาอยู่


 4.จากนั้นกดปุ่มรูปตารางที่มีดินสอตามรูปด้านล่างนี้


5.จากนั้นจะมีหน้าต่างขึ้นมาให้เลือก table ที่เราต้องการแก้ไขให้เลือกอันที่เราแก้ไขใน Models ไปหลังสุด


6.จะปรากฎหน้าต่างรูปแบบนี้ขึ้นมาโดยในส่วนของ Field name และ Field type จะแตกต่างกัน จาากจุดนี้ให้ย้อนกลับไปดูที่ Terminal ในข้อ 2 ที่ให้เปิดไว้ ว่ามีอะไรที่ใน SQLite database browser นั้นไม่มีแต่ใน Terminal มี โดยใน Terminal จะเป็น Field name เว้นวรรคแล้วตามด้วย Field type โดยชื่อของ table จะอยู่ด้านบนระบุไว้เรียบร้อยแล้ว


7.จากข้อ 6 ในตัวอย่างนี้นั้นตัว Description เป็นตัวที่ไม่มีก็ให้เรากดปุ่ม Add field จากนั้น กรอก Field name เป็นชื่อของตัวที่ขาดหายไปจาก table


8.ให้เลือกเลือก Field type ใส่ซึ่งถ้าไม่มีแบบที่ตรงกับ Terminal ก็ให้กดปุ่ม ... ด้านข้างแล้วพิมเอง


9.กด OK และ Create

10.ทำซ้ำข้อ 4-9 จนใน db.sqlite3 ของเรามี table ตรงกับใน terminal ทั้งหมดก็ให้กด save แล้วปิดโปรแกรมลองรัน Django แล้วทดสอบ Web Application ของเราอีกครั้ง
Read more ...

Work 1 Resource Tracking - Update 1

Resource Tracking - Account Statement

1.ทำหน้า Add Income และ Add Expenses โดยใช้ Form ใน Templates รับค่าจากหน้า Web Browser ไปจัดการต่อใน Python Code Views โดยมีการเช็คเงื่อนไขไว้หากค่าที่รับมานั้นติดลบ หรือไม่ใช่ตัวเลขจะเด้งกลับหน้า Add Income หรือ Add Expenses ที่ส่งค่ามาให้ก่อนหน้านี้เพื่อให้ใส่ค่าใหม่อีกครั้ง

2.ทำการเปลี่ยนรูปแบบ Field ของ Asset และ amount ใน Class Profile และ income_expenses จาก IntegerField ไปเป็น FloatField เพื่อให้รองรับค่าตัวเลขแบบจุดทศนิยมได้

3.สร้างหน้า View Asset ขึ้นโดยเป็นหน้าที่แสดงรายการทั้งหมดของบัญชีที่ใส่ค่าไว้ในรูปแบบของตารางพร้อมทั้งแสดงเงินคงเหลือจากรายรับและรายจ่ายทั้งหมดที่หักลบกันแล้ว

4.สร้าง Link กลับไปยังหน้าหลักให้ Template ทั้งหมด และ สำหรับ View Asset จะมี Link ไปยังหน้า Add Income และ Add Expenses ให้เป็นพิเศษด้วย

5.ปรับปรุง Templates ทั้งหมดให้เป็น HTML Code เต็มรูปแบบ ปรับการแสดงผลสำหรับทศนิยมเป็น 2 ตำแหน่งและใส่ Comma เมื่อเลขเกินหลักร้อยอัตโนมัติ นอกจากนี้ยังใช้ Link แบบ Dynamic ด้วย namespace จาก Urls ทั้งหมด

6.แก้ไข Models อีกครั้งโดยเพิ่มตัวข้อที่ชื่อ Accountname ใน Profile และ Description ใน income_expenses เป็น CharField ที่กำหนดความยาวสูงสุดไว้ที่ 200 ตัวอักษร

7.สร้างหน้า Index Page แรกสุด ตอนที่พิม http://127.0.0.1:8000/ โดยมีลิ้งค์เพื่อเข้าไปยัง App Account_Statement และ Admin

ภาพตัวอย่างหน้า Index http://127.0.0.1:8000/


ภาพตัวอย่างหน้า Add Income และ Add Expenses



ภาพตัวอย่างหน้า Add Income เมื่อใส่ตัวอักษรหรือเลขติดลบในช่อง Input


ภาพตัวอย่างหน้า View Asset


Read more ...

วันพฤหัสบดีที่ 2 มกราคม พ.ศ. 2557

Work 1 Resource Tracking - Start

Resource Tracking App

1.เริ่มต้นโดยการสร้าง Project ด้วย Django 1.6 โดยโปรเจคชื่อ Resource_Tracking

2.ทำการตั้งค่าพื้นฐานเช่น Time Zone .hgignore เป็นต้น

3.เริ่ม App ชื่อ Account_Statement โดยเป็น App ที่ Tracking เรื่องทางด้านการเงินในรูปแบบของบัญชีรายรับ-รายจ่าย

4.แก้ไข setting โดยการกำหนด TEMPLATE_DIRS ไปยัง Directory ที่สร้างไว้

5.สร้าง Class ใน Models 2 Class ชื่อ Profile และ income_expense

    5.1 โดย Profile เป็น Class ที่เก็บข้อมูล Firstname, Lastname และ asset ซึ่ง Firstname และ Lastname นั้นเอาไว้เก็บชื่อและนามสกุล ส่วน asset เอาไว้เก็บยอดเงินคงเหลือจากรายรับและรายจ่ายทั้งหมดไว้

    5.2 ส่วน income_expenses เป็น Class ที่เป็นตัวลูกของ Profile อีกทีโดยใน Class จะประกอบด้วย in_or_ex, amount และ pub_date ซึ่ง in_or_ex เป็น Choice ที่มีให้เลือก 2 ตัวคือ income กับ expenses เอาไว้ใช้ระบุว่ารายการนี้เป็นรายรับหรือรายจ่าย amount เอาไว้รับค่าจำนวนเงินที่เปลี่ยนแปลงไป และ pub_date เอาไว้ระบุเวลาและวันที่ในการบันทึกค่า

6.สร้างหน้า Index สำหรับการแสดง Account ทั้งหมดที่มีใน Database และเลือกเข้าไปแก้ไข Account ใด
ภาพตัวอย่างหน้า Index


7.สร้างหน้า Menu หลักสำหรับเลือกการทำรายการโดยแบ่งออกเป็น 4 รายการดังนี้
    - Adding income
    - Adding expenses
    - View asset
    - Edit income & expenses

ภาพตัวอย่างหน้า Menu

Read more ...

วันพุธที่ 1 มกราคม พ.ศ. 2557

Django Tutorial Part 5 - Automated Testing

     การทำ Web Application นั้นย่อมมีโอกาสที่จะเกิด Bug ต่างๆขึ้นได้ซึ่งถ้าหากเราต้องนั่งตรวจสอบเองทั้งหมดก็ย่อมทำได้ แต่หาก Web Application ของเรามีขนาดใหญ่ มีความซับซ้อนสูง การที่จะนั่งตรวจสอบเองย่อมไม่ใช่เรื่องง่าย ดังนั้นจึงมีวิธีในการตรวจสอบอย่างง่ายๆโดยการเขียน Test

---Automated Testing---

1.มาทดลองการทดสอบ Bug ด้วยตัวเองกันก่อน เริ่มต้นให้ใช้ Shell แล้วพิมคำสั่งดังนี้


    จะเห็นได้ว่า future_poll นั้นจะเป็น Poll ที่มีวันที่ในการ Published เป็นอีก 30 วันข้างหน้าและเมื่อเราเรียก was_published_recently นั้นควรจะได้ Output เป็น True ก็ต่อเมื่อเวลาที่ Published กับเวลา ณ ตอนเรียก was_published_recently นั้นห่างกันไม่เกิน 1 วันแต่เวลาที่ Published ของ future_poll นั้นเป็นอีก 30 วันข้างหน้าซึ่งไม่ควรจะได้ True แบบนี้นั่นเอง

2.แก้ไขไฟล์ tests.py ที่อยู่ในโฟลเดอร์ของ Poll ให้เป็นดังนี้
import datetime

from django.utils import timezone
from django.test import TestCase

from polls.models import Poll

class PollMethodTests(TestCase):

    def test_was_published_recently_with_future_poll(self):
        """
        was_published_recently() should return False for polls whose
        pub_date is in the future
        """
        future_poll = Poll(pub_date=timezone.now() + datetime.timedelta(days=30))
        self.assertEqual(future_poll.was_published_recently(), False)
    จาก โค้ดใน tests.py ที่เขียนไปนั้นเป็นการประกาศ future_poll ซึ่งให้วันที่ published เป็นอีก 30 วันข้างหน้าจากนั้น self.assertEqual นั้นจะนำเอา Output ที่ได้จากการเรียก future_poll.was_published_recently() มาเทียบว่าได้ False หรือไม่หากได้ False ก็จะเทสผ่าน หากไม่ได้ False ก็จะเกิด Error ฟ้อง Fail ขึ้น

จากนั้นใน terminal ลองพิมคำสั่ง python manage.py test polls จะได้ผลลัพธ์ดังนี้


    เหตุผลที่ FAIL นั้นก็เพราะ Test ที่เราเขียนกับผลของ was_published_recently นั้นไม่เป็นตามที่เรากำหนดไว้ซึ่งควรจะเป็น False แต่ได้ True นั่นเอง

3.แก้ไข Bug ของ was_published_recently โดยเข้าไปแก้ไข models.py ดังนี้
def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <  now
    จาก was_published_recently() ที่แก้ไขไปนั้นจะเป็นการเช็คว่าเวลาที่ published ไว้นั้นยังไม่เกินเวลาปัจจุบัน และยังไม่เกิน 1 วันก็จะ Return True แต่หากไม่เข้ากรณีใดกรณีนึงก็จะ Return False ทันที

จากนั้นลองพิมคำสั่ง python manage.py test polls จะได้ผลลัพธ์ดังนี้


    จากการที่เราแก้ไขใน was_published_recently() ไปแล้วนั้นทำให้ผลลัพธ์ที่ออกมานั้นถูกต้องผลการรัน tests เลยผ่านไม่เกิด Fail แบบในรอบที่แล้ว

4.เพิ่ม Test อีก 2 กรณีให้ Poll โดยแก้ไขไฟล์ tests.py ดังนี้
def test_was_published_recently_with_old_poll(self):
    """
    was_published_recently() should return False for polls whose pub_date
    is older than 1 day
    """
    old_poll = Poll(pub_date=timezone.now() - datetime.timedelta(days=30))
    self.assertEqual(old_poll.was_published_recently(), False)

def test_was_published_recently_with_recent_poll(self):
    """
    was_published_recently() should return True for polls whose pub_date
    is within the last day
    """
    recent_poll = Poll(pub_date=timezone.now() - datetime.timedelta(hours=1))
    self.assertEqual(recent_poll.was_published_recently(), True)
    ใน test_was_published_recently_with_old_poll นั้นสร้างตัวแปรชื่อ old_poll โดย published เป็นเวลา ณ ปัจจุบันแล้วลบออกไป 30 วัน ซึ่งผลลัพธ์ที่ได้ควรจะเป็น False
    ส่วน  test_was_published_recently_with_recent_poll จะมีตัวแปรชื่อ recent_poll ซึ่งเอาเวลาปัจจุบันลบออกไป 1 ชั่วโมงซึ่งผลลัพธ์ที่ควรได้จะเป็น True นั่นเอง

5.ลองทดสอบ Client ผ่าน Shell โดยพิมคำสั่งตามนี้







    จาก shell ที่รันนั้นจะเป็นการ get status จากการเรียกไปยัง Server ตาม html ที่กำหนดแล้วแสดงผลออกมาพร้อมกับสร้าง poll ขึ้นมาใหม่ 1 อันชื่อ Who is your favorite Beatle แล้วบันทึกลงใน DB ของเรา

6.ปรับปรุง view จะเห็นได้ว่ามีกรณีที่ published นั้นอาจจะอยู่ในอนาคตได้ดังนั้น published ที่อยู่ในอนาคตก็ไม่ควรจะแสดงผลในตอนนี้เช่นกัน ให้เข้าไปแก้ไข IndexView views.py ดังนี้

def get_queryset(self):
    """
    Return the last five published polls (not including those set to be
    published in the future).
    """
    return Poll.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]
และเพิ่ม from django.utils import timezone เข้าไปด้วย
และเพิ่มส่วนทดสอบในไฟล์ tests.py เข้าไปด้วยดังนี้
from django.core.urlresolvers import reverse
def create_poll(question, days):
    """
    Creates a poll with the given `question` published the given number of
    `days` offset to now (negative for polls published in the past,
    positive for polls that have yet to be published).
    """
    return Poll.objects.create(question=question,
        pub_date=timezone.now() + datetime.timedelta(days=days))

class PollViewTests(TestCase):
    def test_index_view_with_no_polls(self):
        """
        If no polls exist, an appropriate message should be displayed.
        """
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_poll_list'], [])

    def test_index_view_with_a_past_poll(self):
        """
        Polls with a pub_date in the past should be displayed on the index page.
        """
        create_poll(question="Past poll.", days=-30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_poll_list'],
            ['<Poll: Past poll.>']
        )

    def test_index_view_with_a_future_poll(self):
        """
        Polls with a pub_date in the future should not be displayed on the
        index page.
        """
        create_poll(question="Future poll.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, "No polls are available.", status_code=200)
        self.assertQuerysetEqual(response.context['latest_poll_list'], [])

    def test_index_view_with_future_poll_and_past_poll(self):
        """
        Even if both past and future polls exist, only past polls should be
        displayed.
        """
        create_poll(question="Past poll.", days=-30)
        create_poll(question="Future poll.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_poll_list'],
            ['<Poll: Past poll.>']
        )

    def test_index_view_with_two_past_polls(self):
        """
        The polls index page may display multiple polls.
        """
        create_poll(question="Past poll 1.", days=-30)
        create_poll(question="Past poll 2.", days=-5)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_poll_list'],
             ['<Poll: Past poll 2.>', '<Poll: Past poll 1.>']
        )
    โดย test_index_view_with_no_polls, test_index_view_with_a_future_poll ผลลัพธ์ที่ได้ต้องออกมาเป็น [] เพราะ Future ไม่ควรแสดงผล และ no_polls ย่อมต้องไม่มีอะไรมาแสดงแน่นอน

    ในส่วนของ test_index_view_with_future_poll_and_past_poll, test_index_view_with_a_past_poll ผลลัพธ์ที่ออกก็จะได้เป็น ['<Poll: Past poll.>'] เนื่องจากการแสดงผลจะต้องแสดงเฉพาะ poll ที่ published แล้วและวันที่ published ไม่ได้อยู่ในอนาคต

    สุดท้าย test_index_view_with_two_past_polls เมื่อมี poll 2 ที่ถูก published แล้ววันที่ published นั้นไม่ได้อยู่ในอนาคตผลลัพธ์ก็จะได้ออกมาเป็น ['<Poll: Past poll 2.>', '<Poll: Past poll 1.>']

    จากข้างต้นหาก test กรณีไหนแล้วไม่เป็นไปตามข้างต้นแล้วนะผลการ test จะออกมาก Fail แต่หากกรณีไหนตรงก็จะผ่านได้ซึ่งถ้ามีกรณีไหนผิดเราก็สามารถกลับไปแก้ไขในส่วนของ views.py ได้

7.ทดสอบ DetailView เริ่มโดยการเพิ่ม method เข้าไปใน Class DetailView ที่อยู่ภายใน views.py ดังนี้
def get_queryset(self):
    """
    Excludes any polls that aren't published yet.
    """
    return Poll.objects.filter(pub_date__lte=timezone.now())
และเพิ่มโค้ดเข้าไปใน tests.py ดังนี้
class PollIndexDetailTests(TestCase):
    def test_detail_view_with_a_future_poll(self):
        """
        The detail view of a poll with a pub_date in the future should
        return a 404 not found.
        """
        future_poll = create_poll(question='Future poll.', days=5)
        response = self.client.get(reverse('polls:detail', args=(future_poll.id,)))
        self.assertEqual(response.status_code, 404)

    def test_detail_view_with_a_past_poll(self):
        """
        The detail view of a poll with a pub_date in the past should display
        the poll's question.
        """
        past_poll = create_poll(question='Past Poll.', days=-5)
        response = self.client.get(reverse('polls:detail', args=(past_poll.id,)))
        self.assertContains(response, past_poll.question, status_code=200)
     เริ่มต้นที่ test_detail_view_with_a_future_poll ผลลัพทธ์ที่ได้ต้องได้ status_code เป็น 404 เพราะ future poll เราต้องไม่แสดงผลนั่นเอง

    จากนั้น test_detail_view_with_a_past_poll หากเป็น past poll นั้นผลลัพธ์ที่ได้ต้องได้ status_code เป็น 200 และแสดง question ด้วย

    จากข้างต้นหาก test กรณีไหนแล้วไม่เป็นไปตามข้างต้นแล้วนะผลการ test จะออกมาก Fail แต่หากกรณีไหนตรงก็จะผ่านได้ซึ่งถ้ามีกรณีไหนผิดเราก็สามารถกลับไปแก้ไขใน ส่วนของ views.py ได้

    จาก Tutorial Part 5 ที่ได้ทำมานั้นเราสามารถเขียนโค้ดเพื่อใช้ในการทดสอบว่า Web Application ของเรานั้นมี Bug หรือปัญหาที่ส่วนใดรึเปล่าซึ่งจะสะดวกมากในอนาคตหากโปรแกรมของเรามีขนาดใหญ่ ถ้าหากการแก้ไขจุดๆเดียวมีผลกับหลายๆที่ก็จะช่วยย่นระยะเวลาในการตรวจสอบโปรแกรมของเราลงไปได้อีกด้วย
Read more ...

Assignment 3 - Python txt to csv

Python txt to csv


    จากใน Assignment 3 - Python HTML Profile DB นั้นข้อมูลที่เรานำมาใช้เป็นไฟล์ .txt ซึ่งเราสามารถเปิดอ่านได้ก็จริงแต่การแสดงผลนั้นหากข้อมูลมีจำนวนมากๆ ก็สามารถทำให้สับสนกับข้อมูลที่แสดงอยู่ได้ ดังนั้นทางออกของปัญหานี้คือเปลี่ยนการเก็บข้อมูลจากเดิมที่เป็น .txt ไปเป็น .csv
    ซึ่งไฟล์ .csv นั้นเราสามารถใช้โปรแกรมจำพวก Spreadsheet เช่น LibreOffice Calc , Microsoft Excel และ Numbers เป็นต้นซึ่งจะแบ่งข้อมูลออกมารูปแบบของตารางทำให้เราสามารถอ่านได้ง่ายขึ้น โดยรูปแบบในการแบ่งมีตัวอักษรให้เลือกหลายแบบเช่น Tab, Comma, Semicolon, Space หรือแล้วแต่เราจะกำหนดก็ได้


    ดังนั้นหากเรามีข้อมูลจำนวนมากๆวิธีการที่จะเปลี่ยนจาก .txt มาเป็น .csv ที่ง่ายที่สุดคือการนำโปรแกรมเข้าช่วยในการจัดการ
#!/usr/bin/env python
file = open("DB.txt","r")
all_line = file.readlines()
new_data = []
for i in all_line:
    new_data.append(i.replace(" \\",";"))
file = open("DB.csv","w")
for j in new_data:
    file.write(j)
file.close()
print "Change txt to csv Complete"
     โดยเริ่มต้นนั้นเปิดไฟล์ DB.txt แล้วอ่านทีละบรรทัดมาเก็บไว้ใน all_line จากนั้นประกาศ List ขึ้นมาใหม่ที่ชื่อ new_data จากนั้นนำข้อมูลใน List all_line มาทีละตัวโดยใช้คำสั่ง replace ซึ่งเป็น API พื้นฐานของ String โดยให้เปลี่ยนจาก \\ เป็น ; แล้วนำไปเก็บไว้ใน new_data จากนั้นเขียนข้อมูลใน new_data ทั้งหมดลงไปในไฟล์ DB.csv แล้วทำการปิดไฟล์ จากนั้น print Change txt to csv Complete ออกทางหน้าจอ

    จะเห็นได้ว่าเมื่อเราเปลี่ยนการเก็บข้อมูลจากแบบ .txt มาเป็น .csv แล้วนั้นหากเราต้องการแก้ไขข้อมูลนั้นก็สามารถทำได้ง่ายกว่าเดิมมากเพราะทุกอย่างทุกจัดให้อยู่ในรูปแบบของตารางโดยโปรแกรมประเภท Spreadsheet ซึ่งดีกว่าการใช้ text editor มาแก้ไขใน .txt เป็นอย่างมาก
Read more ...