วันพฤหัสบดีที่ 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 ...

วันอังคารที่ 31 ธันวาคม พ.ศ. 2556

Assignment 3 - Python HTML Profile DB

Python HTML Profile DB


    โดยข้อมูลที่นำมาสร้างเป็น HTML Profile นี้นั้นกำหนดรูปแบบไว้เป็นไฟล์ .txt โดยข้อมูลของแต่ละคนจะใช้ความยาว 1 บรรทัดมีรูปแบบดังนี้
StudentID \Name \Surname \Nickname \Birthday \Age \Sex \Religion \Weight \Height \E-mail \Address \Facebook \Phone
ตัวอย่างข้อมูลที่ได้เก็บไว้เพื่อใช้สร้าง HTML Profile
StudentID \Name \Surname \Nickname \Birthday \Age \Sex \Religion \Weight \Height \E-mail \Address \Facebook \Phone
5311564149 \Chawatvish \Worrapoj \best \09.11.1991 \22 \male \Buddhism \92 \185 \bestwhatup@gmail.com \418 M.2 Wongpong Pranburi Prachuapkhirikhan \facebook.com/bestwhatup \0811736937
5401012631025 \Klanarong \Raluek \kla \12.11.1992 \21 \male \Buddhism \60 \172 \kla_223@hotmail.com \4 M.4 Praputtabat Changklang Nan \facebook.com/kla223 \0824976605
5211164370 \Suwadee \Piyawartsopon \A \21.06.1990 \23 \female \Buddhism \53 \164 \p.suwadee_a@hotmail.com \47/2 M.12 Huaima Muang Phrae \facebook.com/alis492 \0811804841
5311564164 \Chukieat \Boontae \Poa \20.09.1987 \26 \male \Buddhism \80 \175 \poashadow@hotmaill.com \52/288 Phraramhokmansion Bang O Bang Phlat Bangkok \facebook.com/poashadow \0809004406
5401012630240 \Siriwimon \Sunthon \Jaa \16.07.1992 \21 \female \Buddhism \48 \162 \darkblood_rockaholic@hotmaill.com \434 Village No.3 Wangkrajae Sub-Distric Meong Trat Distric,Trat \facebook.com/siriwimon.sunthon \0849335018
5401012630142 \Parichat \Larwongsa \Tai \28.01.1993 \20 \female \Buddhism \57 \160 \tqy_naka@hotmail.com \346 Bangmod Chomthong Bangkok 10150 \facebook.com/parichat larwongsa \0906782882
5501012630109 \Thanakorn \Nguansiew \Boy \26.06.1993 \20 \male \Buddhism \106 \180 \podmeax@gmail.com \4 M.1 Thaka Amphawa Samutsongkhram 75110 \facebook.com/mheeboy \0836939551
5501012620073 \Wittawin \Kahuttanaseth \Dew \23.10.1993 \20 \male \Catholic \64 \155 \wittawin_k@hotmail.com \189/41 Siriya Homeland Watcharaphon rd. ThaRaeng Bangken Bangkok 10220 \facebook.com/wittawin.kahuttanaseth \0877990445
5501012630133 \Tatchagon \Koonkoei \Kol \02.06.1993 \20 \male \Buddhism \50 \168 \o_k_t@hotmail.com \111/1 M.3 Banmai Thamuang Kanchanaburi \facebook.com/tatchagon \0826810461
5401012620082 \Chonnipa \Yenpensuk \Myu \29 January 1993 \20 \Female \Buddhism \39 \155 \bahimuch@hotmail.com \65/4 M.5(93) Paknumkrajomthong Lane Rachaprek Road Bangphom Subdistrict Talingchan District Bangkok 10170 \facebook.com/za.tabo.za \0809783200
5401012630185 \Pokai \Nitiroj \Joint \19.11.1992 \21 \Male \Buddhism \80 \176 \pokai.nitiroj@gmail.com \111/472 Mantana(onnuch - outer ring) Dokmai Prawet Bangkok 10250 \facebook.com/jibjoint \0836029000
5211163182 \Teejuta \Kaewthong \Mimz \02.11.1990 \23 \Female \Buddhism \55 \174 \takachi_pada@hotmail.com \314/434 DonmuengVilla SongPraPa Road,Donmueng Bangkok 10210 \facebook.com/teejuta.kaewthong \0861075824
 ในส่วนของ Python Code นั้นเป็นดังนี้
#!/usr/bin/env python

def make_index(mData):
    body = ""
    for l in range(len(mData)):
        body = body + """<a href=./htmlPage/""" + str(l) + """.html>""" + mData[l][0] + """</a><br><br>"""
    file = open("./index.html", 'w')
    file.write("""
    <html>
    <head>
        <title>Index of Profile</title>
    </head>
    <body bgcolor="skyblue"><font color="brown">
    <center>
    <font size="10">Index of Student Profile by StudentID</font><br><br>
    """ + body + """
    </center>
    </body>
    </html>""")
    file.close()
    print "Generate Index HTML Complete"

def make_html(Maxpage, mi, mData):
    Linkpage = ""
    if mi==0:
        Linkpage = Linkpage + """<p style="float: left; width: 33.33%; text-align: left;"></p>"""
    else:
        Linkpage = Linkpage + """<p style="float: left; width: 33.33%; text-align: left;"><a href="./"""+str(mi-1)+""".html">Previous</a></p>"""
    Linkpage = Linkpage + """<p style="float: left; width: 33.33%; text-align: center;"><a href=./../index.html>Back To Index Page</a></p>"""
    if mi<Maxpage-1:
        Linkpage = Linkpage + """<p style="float: left; width: 33.33%; text-align: right;"><a href="./"""+str(mi+1)+""".html">Next</a></p>"""
    file = open("./htmlPage/"+str(mi)+".html", 'w')
    file.write("""
    <html>
    <head>
        <title>Profile  of """ + mData[0] + """</title>
    </head>
    <body bgcolor="skyblue"><font color="brown">
        StudentID : """ + mData[0] + """<br><br>
        Name : """ + mData[1] + "   " + mData[2] + """<br><br>
        Nickname : """ + mData[3] + """<br><br>
        Birthday : """ + mData[4] + """<br><br>
        Age : """ + mData[5] + """<br><br>
        Sex : """ + mData[6] + """<br><br>
        Religion : """ + mData[7] + """<br><br>
        Weight : """ + mData[8] + """<br><br>
        Height : """ + mData[9] + """<br><br>
        E-mail : """ + mData[10] + """<br><br>
        Address : """ + mData[11] + """<br><br>
        Facebook : """ + mData[12] + """<br><br>
        Phone Number : """ + mData[13][:10] + """<br></font>
        """ + Linkpage + """
    </body>
    </html>""")
    file.close()
    print "Generate HTML Complete " + str(mi)
  
file = open("./DB.txt", "r")
all_line = file.readlines()
all_line.pop(0)
all_line.sort()
All_Data = []
for i in all_line:
    All_Data.append(i.split(" \\"))
for k in range(len(All_Data)):
    make_html(len(All_Data), k, All_Data[k])
make_index(All_Data)
    เริ่มต้นนั้นโปรแกรมนี้จะทำการเปิดไฟล์ DB.txt ขึ้นมาอ่านแล้วทำการอ่านแต่ละบรรทัดไปเก็บไว้ใน List ที่ชื่อ all_line แล้วทำการ pop บรรทัดแรกออกเพราะบรรทัดแรกในไฟล์นั้น DB.txt นั้นเป็นหัวข้อของข้อมูลที่จะใส่ซึ่งเราไม่ต้องการนำหัวข้อตรงนี้มาใช้ จากนั้น sort ข้อมูลโดยจะเรียงตามลำดับเลขที่นักศึกษา จากนั้นสร้าง List ขึ้นมาใหม่อีกอันชื่อ All_Data แล้วจึงนำข้อมูลใน List ของ all_line แต่ละตัวมาใช้คำสั่ง split ซึ่งเป็น API พื้นฐานของ String ที่มากับ Python หลังจาก split แล้วก็ให้นำข้อมูลไปเก็บใน List All_Data ที่สร้างไว้ทำให้ข้อมูลใน All_Data นั้นเก็บไว้ในรูปแบบของ List ซ้อน List อีกที จากนั้นจึงเรียกใช้ฟังก์ชั่นเพื่อสร้างไฟล์ HTML ซึ่งโปรแกรมนี้จะมีฟังก์ชั่น 2 ฟังก์ชั่น คือ make_html และ make_index

    โดย make_html นั้นมี Argument 3 ตัวคือ Maxpage, mi, mData โดย Maxpage คือจำนวนหน้าของ Profile ทั้งหมดซึ่งมีค่าตามความยาวของ List All_Data , mi เป็นเลขใช้สำหรับระบุลำดับที่จะใช้สร้าง HTML Page และ mData เป็น List ของข้อมูลที่จะนำไปใส่ใน HTML Page ที่ได้จากการ split ก่อนหน้านี้นั่นเอง จากนั้นสร้างตัวแปร Linkpage จากนั้นทำการเช็คเงื่อนไขหาก mi เป็นตัวแรกจะไม่ใส่ Link สำหรับ Previous หรือหากเป็นตัวสุดท้ายก็จะไม่ใส่ Next เช่นกันจากนั้นจึงสร้างไฟล์ HTML โดยใช้คำสั่งของ file มาเขียนโค้ด HTML ลงไปโดยดึงข้อมูลจาก mData ไปใส่ระหว่างการเขียนไฟล์ด้วยจากนั้นปิดท้ายด้วยการนำ Linkpage ไปใส่ไว้ล่างสุดของ HTML Code แล้วทำการปิด file จากนั้น print คำว่า Generate HTML Complete ตามด้วยเลขหน้าออกทางหน้าจอ

    และ make_html มี Argument 1 ตัวคือ mData ซึ่งเป็นตัวแปรที่เก็บข้อมูลทั้งหมดไว้ จากนั้นเริ่มต้นด้วยการสร้างตัวแปรชื่อ Body แล้ววน loop ตามความยาวของ mData เพื่อเก็บ Code ที่ใช้สร้างลิ้งค์ไปยังไฟล์ HTML ของแต่ละเลขประจำตัวจากนั้นจึงเขียนลงไฟล์ที่ชื่อ index.html แล้วทำการปิดไฟล์ print คำว่า Generate Index HTML Complete ออกทางหน้าจอ

    จากโปรแกรมนี้จะเห็นได้ว่าเราสามารถนำข้อมูลจากภายนอกมาใช้เป็นข้อมูลในโปรแกรมของเราและนำไปสร้างเป็นไฟล์ HTML ที่ใช้ในการแสดงผลอีกด้วยโดยการใช้ file นั้นจะเห็นว่า file = open("./DB.txt", "r") ในคำสั่ง open นั้นจะประกอบไปด้วยชื่อไฟล์ และ Mode ซึ่งจากที่ยกตัวอย่างนัั้นจะมีทั้ง "r" และ "w" โดย "r" นั้นจะเป็นโหมดในการอ่านเพียงอย่างเดียวเท่านั้น ส่วน "w" จะเป็นการเขียนไฟล์เท่านั้นหากมีไฟล์ชื่อนี้อยู่แล้วจะลบของเก่าทิ้งแล้วเขียนลงไปใหม่ นอกจากนี้ยังมีอีกโหมดนั่นก็คือ "a" ซึ่งโหมดนี้จะเป็นการเขียนไฟล์เพิ่มต่อจากของเดิม และสุดท้ายโหมด "r+" ซึ่งโหมดนี้สามารถทำได้ทั้งอ่านและเขียนไฟล์ได้เลย

โดยได้ศึกษาการใช้ open จากเว็บ python.org
โดยได้ศึกษาการเขียนโค้ด HTML จากเว็บ w3schools.com
Read more ...

วันอาทิตย์ที่ 15 ธันวาคม พ.ศ. 2556

งานครบรอบ 50 ปีวิศวะ มจพ.

บูธในงานที่สนใจก็คือบูทของ FRECON

ซึ่งบูธซึ่งเป็นบูธที่เกี่ยวข้องกับมอเตอร์ไฟฟ้าทั้งในรูปแบบของ Inverter หรือ Servo Motor




ภาพ Oscilloscope ที่จับสัญญาณจาก Inverter


ภาพภายในของ Inverter


ภาพมอเตอร์ที่ต่อกับ Inverter ซึ่งเป็นแบบไร้แปรงถ่าน


ภาพตัวอย่างมอเตอร์แบบปกติ
 

ภาพ Servo Motor พร้อมตัวควบคุม


ภาพตัวควบคุม Servo Motor


ภาพ Servo Inverter


ภาพ Servo Motor


    เหตุผลที่บูธนี้น่าสนใจก็เพราะว่าชุมควบคุม Servo Motor และ ระบบ Inverter นั้นเริ่มมีให้เห็นในชีวิตประจำวันของเราบ้างโดยส่วนใหญ่จะเป็น Inverter เช่นใน แอร์ เป็นต้น และสิ่งของเหล่านี้ก็มีความเกี่ยวข้องทางด้านคอมพิวเตอร์อยู่บ้าง ในส่วนของชุดควบคุม Servo Motor นั้นมีหน้าจอที่ใช้ในการควบคุมชุด Servo Inverter และ Servo Motor ซึ่งต้องใช้โปรแกรมในการเขียนควบคุมนั่นเองโดยจากตัวอย่างที่ได้เห็นนั้นการหมุนของ Servo Motor ทั้งสองตัวมีความแม่นยำและความเร็วสูงมาก
Read more ...

วันพุธที่ 11 ธันวาคม พ.ศ. 2556

สรุป Django w6-2

ความรู้พื้นฐานในการใช้งาน Django: The Web framework ประกอบด้วยส่วนหลักๆ 6 ส่วนดังนี้

1.Models (Apps) คือ การสร้าง Web Application แบบง่ายๆซึ่งมีความสามารถในการเก็บข้อมูล (Database) ได้ใน 1 Project สามารถมีมากกว่า 1 Models (Apps) ได้
ศึกษาการใช้งาน Models (Apps) คลิกที่นี่

2.Admin คือ หน้าของผู้ดูแลระบบ สามารถแก้ไข, เพิ่ม, ดู, ลบ ข้อมูลต่างๆที่อยู่ใน Database ได้ซึ่งหน้าแอดมินมีการจัดรูปแบบการแสดงผลได้หลายรูปแบบ
ศึกษาการใช้งาน Admin คลิกที่นี่

3.Views คือ Python Code มีไว้เพื่อจัดการรูปแบบการแสดงผลของหน้าเว็บเพจ ซึ่งจะประกอบด้วยฟังก์ชั่นให้ Urls เรียกใช้เวลามีการเรียกเว็บเพจขึ้นมาแสดงผล
ศึกษาการใช้งาน Views จาก Django Tutorial คลิกที่นี่ หรือจาก Djangobook คลิกที่นี่

4.Urls คือ ส่วนที่ใช้จัดการตรวจสอบเช็ค Address ว่าตรงกับ Address ที่ระบุไว้หรือไม่หากตรงก็จะไปเรียกฟังก์ชั่นใน Views ขึ้นมาแสดงผลทาง Browser หากไม่ตรงก็จะ Error Page not found
ศึกษาการใช้งาน Urls จาก Django Tutorial คลิกที่นี่ หรือจาก Djangobook คลิกที่นี่

5.Templates คือ โครงร่างรูปแบบของ HTML Code ที่ใช้ในการแสดงผลซึ่งมีประโยชน์ในด้านความยืดหยุ่นของข้อมูลที่จะแสดงผลสูงเนื่องจากใช้ตัวแปรเป็นตัวกำหนดค่า
ศึกษาการใช้งาน Templates จาก Django Tutorial คลิกที่นี่ หรือจาก Djangobook คลิกที่นี่

6.Form คือ การสร้าง User Input ผ่านทาง Web browser ใน HTML Code ซึ่ง Input ที่รับค่ามานั้นเราสามารถนำไปใช้ได้ตามต้องการขึ้นกับฟังก์ชั่นที่เรากำหนด
ศึกษาการใช้งาน Form คลิกที่นี่
Read more ...

วันอังคารที่ 10 ธันวาคม พ.ศ. 2556

Djangobook - Templates

ในบทความนี้นั้นเราจะมาทดลองการใช้งาน Template ใน Django กันครับโดยเริ่มต้นให้สร้าง Folder ที่ชื่อ Templates ขึ้นใน Project ของเราก่อนจากนั้นให้ไปแก้ไขในไฟล์ setting.py โดยเพิ่มโค้ดเข้าไปดังนี้

TEMPLATE_DIRS = (
"/home/wittawin/Kim/Stamp/Templates",
# From Django book
# Always use forward slashes, even on Windows.
# Don’t forget to use absolute paths, not relative paths.
)

    โดยใน String ที่ใส่เพิ่มเข้าไปนั้นให้แก้ไขตาม Directory ที่แต่ละคนสร้างไว้เพื่อเก็บ Templates ซึ่งเหตุผลที่ต้องเพิ่มโค้ดชุดนี้เข้าก็เพื่อเป็นการกำหนดให้ Django รู้ว่าเราจะเก็บ Templates ไว้ที่ไหนเพื่อให้ Django รู้ที่อยู่แล้วเข้าไปอ่านไฟล์ Templates ในนั้นได้

จากนั้นให้เข้าไปเพิ่มโค้ดเข้าไปในไฟล์ urls.py ดังนี้

    url(r'^calendar/$', 'Stamp.views.Years_Calendar'),
    url(r'^calendar(\d+)/$', 'Stamp.views.Years_Calendar'),

จากนั้นไปแก้ไขไฟล์ views.py โดยเพิ่มโค้ดเหล่านี้เข้าไป

from django.shortcuts import render_to_response
import calendar

def Years_Calendar(request,years=2013):
    mycal = calendar.HTMLCalendar(calendar.SUNDAY)
    monthsq1 = ["January","Febuary","March"]
    monthsq2 = ["April","May","June"]
    monthsq3 = ["July","August","September"]
    monthsq4 = ["October","November","December"]
    return render_to_response('Calendar_Template.html', {'listofdate': mycal.yeardayscalendar(int(years)), 'year_show' : years, 'monthq1' : monthsq1, 'monthq2' : monthsq2, 'monthq3' : monthsq3, 'monthq4' : monthsq4, 'value' : 0})

และในโฟลเดอร์ Templates ที่สร้างไว้ตอนต้นให้สร้างไฟล์ที่ชื่อ Calendar_Template.html จากนั้นภายใน Calendar_Template.html ให้ใส่โค้ดดังต่อไปนี้

<html>
    <head>
        <title>Calendar {{ year_show }}</title>
    </head>
    <body bgcolor="skyblue">
        <center><br><font color="white" size = "10">
        Calendar {{ year_show }}</font><br><br>
        <table border="0" cellpadding="2">
    {% for quarters in listofdate %}
        <tr valign="top">
        {% ifequal forloop.counter 1 %}
            {% for month in monthq1 %}
            <td><center><font color="white" size = "6">{{ month }}</font></center></td>
            {% endfor %}
            </tr><tr valign="top">
        {% endifequal %}
        {% ifequal forloop.counter 2 %}
            {% for month in monthq2 %}
            <td><center><font color="white" size = "6">{{ month }}</font></center></td>
            {% endfor %}
            </tr><tr valign="top">
        {% endifequal %}
        {% ifequal forloop.counter 3 %}
            {% for month in monthq3 %}
            <td><center><font color="white" size = "6">{{ month }}</font></center></td>
            {% endfor %}
            </tr><tr valign="top">
        {% endifequal %}
        {% ifequal forloop.counter 4 %}
            {% for month in monthq4 %}
            <td><center><font color="white" size = "6">{{ month }}</font></center></td>
            {% endfor %}
            </tr><tr valign="top">
        {% endifequal %}
        {% for months in quarters %}
            <td><table border="5" cellpadding="10"><tr><td align="center"><font color="white" size = "3">Sun</font></td><td align="center"><font color="white" size = "3">Mon</font></td><td align="center"><font color="white" size = "3">Tue</font></td><td align="center"><font color="white" size = "3">Wed</font></td><td align="center"><font color="white" size = "3">Thu</font></td><td align="center"><font color="white" size = "3">Fri</font></td><td align="center"><font color="white" size = "3">Sat</font></td></tr>
            {% for weeks in months %}
                <tr>
                {% for days in weeks %}
                    {% ifnotequal days 0 %}
                        <td align="right"><font color="white" size = "4">{{ days }}</font></td>
                    {% else %}
                        <td> </td>
                    {% endifnotequal %}
                {% endfor %}
                </tr>
            {% endfor %}
            </table></td>
           
        {% endfor %}
        </tr>
    {% endfor %}
    </table>
        </center>
    </body>
</html>

    หลักการใช้ Template นั้นประกอบไปด้วยสองส่วนนั่นคือ template และ context โดย template นั้นก็หมายถึงไฟล์ HTML ที่ได้เขียนไว้สำหรับการใช้เป็น template นั่นเองส่วน context คือส่วนที่ระบุว่าตัวแปรใน template ที่รอค่าเข้าไปใส่ในตอนใช้งาน template นั้นมีค่าตรงกับตัวแปรใดหรือค่าเท่าใด โดยทั้งสองส่วนนั้นมีความสำคัญสำหรับการใช้ template อย่างมากหากขาดอย่างใดอย่างนึงก็ไม่สามารถใช้ template ได้เมื่อมีครบทั้งสองส่วนแล้วเราก็ต้องทำการ render

    ซึ่งต้องเริ่มด้วยการ import render_to_response เป็นหนึ่งใน API ที่มาจาก django.shortcuts ซึ่งทำหน้าที่ในการนำ context ที่มีไป render ในไฟล์ HTML ที่เป็น template อยู่จากนั้นจึงส่งกลับไปแสดงผลที่ Browser ทันทีเหมือนกับการใช้คำสั่ง HttpResponse เพียงแต่เพิ่มการ render context เข้าไปใน template ก่อนจะ return
return render_to_response('Calendar_Template.html', {'listofdate': mycal.yeardayscalendar(int(years)), 'year_show' : years, 'monthq1' : monthsq1, 'monthq2' : monthsq2, 'monthq3' : monthsq3, 'monthq4' : monthsq4, 'value' : 0})
 จากตัวอย่างจะเห็นว่าส่วนแรกคือชื่อของ template ที่เราจะเป็นโครงในการนำ context ไป render ส่วนต่อมาคือ context จะเห็นว่าตัวทางซ้ายของเครื่องหมาย : คือชื่อของตัวแปรที่อยู่ใน template ส่วนตัวทางขวาของเครื่องหมาย : คือค่าหรือตัวแปรที่จะนำไปใช้นั่นเอง

    ส่วน Calendar นั้นเป็น API ของ python ที่มีมาให้อยู่แล้วซึ่งเราจะใช้ในการสร้าง List ที่เก็บวันที่ของทั้งปีไว้ภายในโดยใช้คำสั่ง mycal.yeardayscalendar(int(years)) เป็น List ที่ประกอบด้วย 4 Quarter ในแต่ละปีและใน List ของแต่ละ Quarter ก็จะประกอบได้เดือน 3 เดือนจากนั้นในแต่ละเดือนก็จะเก็บค่าของสัปดาห์ในเดือนนั้นๆ และในแต่ละสัปดาห์ก็จะเก็บวันที่ของในสัปดาห์นั้นๆโดยเริ่มจากวันที่เรากำหนดให้เป็นวันแรกของสัปดาห์ไว้ตอนสร้าง object
mycal = calendar.HTMLCalendar(calendar.SUNDAY) อย่างในตัวอย่างกำหนดให้เป็นวันอาทิตย์ไว้ จะสังเกตเห็นว่าใน Function def Years_Calendar(request,years=2013): years=2013 นั้นมีไว้ใส่ค่าเป็นค่า พื้นฐานให้หากไม่มีการส่งค่าจาก Urls แต่หากส่งมาก็จะนำค่านั้นมาใช้แทน

ภาพตัวอย่างเมื่อเรียกเพจ 127.0.0.1/calendar


ภาพตัวอย่างเมื่อเรียกเพจ 127.0.0.1/calendar2020


    จากการใช้ Template ในข้างต้นนั้นประการแรกเลยจะเห็นได้ว่าปัญหาอย่างนึงที่ลดลงไปเลยก็คือความสับสนในด้าน Code HTML ที่ผสมกับ python ซึ่งเราจะเจอปัญหานี้ถ้าเราไม่ใช้  Template แบบในตัวอย่างของ Djangobook -  Dynamic Urls and views ซึ่งในตัวอย่าง Code HTML ยังมีจำนวนไม่มาก หากมีจำนวนมากกว่านี้ต้องเกิดความสับสนขึ้นอย่างแน่นอน

    ประการที่สองเราสามารถนำ Template มาใช้ซ้ำได้อีกเพราะ Template เป็นเพียงแค่แบบในการกำหนดโครงสร้างของโค้ดต่างๆโดยสิ่งที่จะนำมาแสดงขึ้นกับ context ที่นำไป render ล้วนๆดังนั้น หากเปลี่ยนค่าของ context ที่จะนำไป render ก็จะได้หน้าต่างที่แสดงผลต่างจากแบบเดิมแล้ว
Read more ...