วันอังคารที่ 21 พฤศจิกายน พ.ศ. 2560

สร้าง Stubs ภาษา C ด้วย cmocka

มีโอกาสได้เปิดวิชา Embedded Software Testing เลยต้องลองกลับไปเขียนภาษา C และ หาไลบรารีสำหรับทดสอบโปรแกรมภาษาซีมาใช้ มีให้เด็กๆ เลือกเล่นหลายๆ ตัวทั้ง Unity (ไม่ไช้โปรแกรมสร้างเกมส์นะครับ :D) CppUTest แต่มาลงตัวที่ CMocka เพราะสามารถใช้ทำ Stubs และ Mock ได้ด้วย

โดยส่วนตัวแล้ว Unity ออกแบบมาค่อนข้างดีสำหรับการทดสอบ embedded แค่เวลาคอมไพล์ยังต้องคอมไพล์ไฟล์ภาษาซีของ Unity เข้าไปร่วมด้วยเลยอาจจะใช้งานยากหน่อย ส่วน CppUTest ก็ออกแนว C++ ไป ถึงแม้ว่าจะใช้ทดสอบโคดภาษาซีได้แต่ก็ไม่ได้เพียวซีจริงๆ CMocka ไม่ได้ออกแบบมาทดสอบ embedded โดยตรงแต่เป็น C ล้วน ใช้การคอมไพล์ช่วยในการสร้าง strub ถึงแม้ว่าเข้าใจยากนิดหน่อย แต่ใช้งานได้ดีทีเดียว

เราจะทดลองสร้าง ฟังก์ชัน calculate โดยรับพรารามิเตอร์ 3 ค่า คือ operator, operand1 และ operand2 แล้วลองเรียก ฟังก์ชัน add แต่ ฟังก์ชัน add เป็น ฟังก์ชันที่เราสร้างขึ้มาเองแล้วถูกเรียกใช้ เราต้อง stub ฟังก์ชัน add เพื่อจะได้ทดสอบเฉพาะการทำงานของฟังก์ชัน calculate เท่านั้น โดยการสร้างฟังก์ชัน __wrap_add ขึ้นมา โดยที่ มี return type และ รับพารามิเตอร์เหมือน ฟังก์ชัน add ทุกอย่าง หากต้องการ stub ฟังก์ชันอื่น นอกจาก add เราก็สารามารถตั้งชื่อโดย __wrap_ เป็นต้น
จากนั้นเราสร้างฟังก์ชันสำหรับทำกรณีทดสอบขึ้นมาชื่อ test_give_10_and_20_with_plus_should_30 โดยให้ operand1 และ operand2 และค่าที่ควรได้ เท่ากับ 10, 20 และ 30 ตามลำดับ เราต้องให้ค่าด้วยว่า ฟังก์ชัน __wrap_add จะให้ค่าถูกต้องเมื่อถูกแทนที่ด้วยฟังก์ชัน add โดยใช้ expect_value แทนการตรวจสอบพารามิเตอร์ที่ได้รับ ต้องตรงกัน และ will_return เพื่อกำหนดค่าให้กับฟังก์ชัน mock_type ว่าจะเป็นค่าอะไร รูปแบบจึงเป็นดังนี้
expect_value(__wrap_add, operand1, input_operand1);
expect_value(__wrap_add, operand2, input_operand2);
will_return(__wrap_add, expected_result);
เริ่มเลย...

// test_add.c
#include <stdio.h>
#include <setjmp.h>

#include "cmocka.h"

int add(int, int);

int calculate(const char operator, int operand1, int operand2){
    int result = 0;
    switch(operator) {
        case '+':
            result = add(operand1, operand2);
            break;
    }
    return result;
}

int __wrap_add(int operand1, int operand2){
    check_expected(operand1);
    check_expected(operand2);

    return mock_type(int);
}

void test_give_10_and_20_with_plus_should_30(void **state){
    (void) state;

    int result;
    int input_operand1 = 10;
    int input_operand2 = 20;
    char operator = '+';
    int expected_result = 30;

    expect_value(__wrap_add, operand1, input_operand1);
    expect_value(__wrap_add, operand2, input_operand2);
    will_return(__wrap_add, expected_result);

    result = calculate(operator, input_operand1, input_operand2);
    assert_int_equal(expected_result, result);
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(test_give_10_and_20_with_plus_should_30),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

หลังจากนั้นลองคอมไพล์ด้วย พารามิเตอร์ด้านล่าง แล้วลองรันดู
$ gcc test_add.c -Wl,--wrap=add -lcmocka -o test_add
$ ./test_add 
[==========] Running 1 test(s).
[ RUN      ] test_give_10_and_20_with_plus_should_30
[       OK ] test_give_10_and_20_with_plus_should_30
[==========] 1 test(s) run.
[  PASSED  ] 1 test(s).
พารามิเตอร์ที่สำคัญสำหรับการคอมไพล์ -Wl,--wrap=add -lcmocka ซึ่งเป็นการบอกให้คอมไพเลอร์รู้ว่า -lcmocka เราจะเชื่อไลบรารี cmocka เข้ามาในโปรแกรม และ --wrap=add ให้คอมไพเลอร์ เปลี่ยนไปใช้ฟังก์ชัน __wrap_add แทน add สังเกตจากไฟล์นี้ ไม่มีการนิยามฟังก์ชัน add มีแค่โปรโตไทป์เท่านั้น ก็สามารถรันโปรแกรมได้ ใครมองหา test harness สำหรับภาษาซีอยู่ลองพิจารณา cmocka ดูนะครับ \o/

วันจันทร์ที่ 26 ตุลาคม พ.ศ. 2558

Barcamp Songkhla IV

หลังจากจบงานก็ควรเขียน blog เป็นที่ระลึกตามธรรมเนียม สำหรับงานครั้งนี้ก็เป็นคนร่วมงานเหมือนครั้งที่แล้ว น้องๆ ที่ภาควิชาและพี่เอ้จาก Tuber เป็นคนจัดงาน โดยรวมแล้วงานออกมาดี ปีนี้มีเบียร์แคมป์ด้วย ถือเป็นครั้งแรกของงานเลย แต่เสียดายหัวข้อน้อยไปหน่อย

พูดอะไรในงาน Barcamp Songkhla IV
ปีนี้เตรียมหัวข้อไปเรื่องเดียวคือ MQTT เป็น Message Passing ตัวนึงที่น่าสนใจมาก เหมาะแก่การนำมาขยายระบบ และประยุกต์ใช้กับ IoT โดยคร่าวๆ แล้วสรุปได้ประมาณนี้

  • พัฒนาโดย IBM และ Arcom เวอร์ชันปัจจุบันเป็นได้รับการรับรองมาตฐานจาก OASIS
  • โปรโตคอลเล็กมากมี header ไม่เกิน 2 byte ทำงานอยู่บน TCP/IP
  • มีลักษณะเป็น Publish/Subscribe จะมีส่วนที่ส่งข้อความออก และรับข้อความเข้าผ่านทาง Message Broker
  • ใช้วิธีการ Topic Maching สำหรับการส่งข้อมูลจาก Publisher ไปยัง Subscriber

เนื่องจากโปรโตคอลมีขนาดเล็กจึงสามารถใช้งานได้ดีบน node ที่มีขนาดเล็ก มีพลังในการประมวลผลน้อย จึงเหมาะกับอุปกรณ์ต่างๆ ใน IoT ด้วย นอกจากนี้ยังมีประเด็นปลีย่อยต่างๆ สามารถดูได้จาก slide



หัวข้อที่น่าสนใจ


บรรยากาศงานเป็นอย่างไร
สำหรับปีนี้บรรยากาศงานโดยรวมดีกว่าปีก่อน แต่คนเข้าร่วมงานน้อยไปหน่อย ส่วนใหญ่ไม่มาเพราะติดธุระ ซึ่งจริงๆ แล้วหากติดธุระจริงๆ ควรจะถอนชื่อออก เพราะมันเป็นการกินที่คนอื่นอีกทั้งเปลืองทรัพยากรอีกด้วย (ข้าวเหลือเยอะมากๆๆ)  ปีนี้เป็นปีแรกที่ต่อด้วย beercamp ในงานได้เชิญ YEC กับรองประธานหอการค้า ของ สงขลามาให้ความรู้แล้วก็พบปะพูดคุยกันด้วย หากมองแนวสตาร์ทอัพแล้วดีมาก เพราะนักพัฒนาจะได้พบกับผู้ลงทุนได้โดยตรง อีกทั้งพอมีเบียร์ อะไรๆ ก็ลื่นไปหมด \o/ อีกเรื่องนึงคือ หัวข้อที่ได้น้อยไปหน่อย ส่วนใหญ่เป็นเจ้าเดิมๆ มีหัวข้อใหม่ไม่มาก เราต้องช่วยกันกระตุ้นวัฒนธรรมแบ่งปันความรู้ให้มากขึ้นกว่าเดิม โดยมากแล้ว หลายๆ คนมาศักยภาพที่จะเป็นสปีกเกอร์ได้สบายแต่ยังไม่กล้าเพราะกลัวว่ายังไม่เจ๋งพอ แต่ในทางกลับกันการเสนอตัวออกมาพูดทำให้เราได้พัฒนาทักษะด้านการเรียบเรียงความรู้หรือการพูดเพิ่มเติม ซึ่งเป็นทักษะที่สำคัญในการดำรงชีวิตของทุกๆ คน หัวข้อก็ไม่จำเป็นต้องเกี่ยวกับ IT ก็ได้ เป็นอะไรก็ได้ที่น่าสนใจ หรือตัวเองเชียวชาญอยู่แล้ว

ส่งท้าย
โดยสรุปแล้วปีนี้ อาหารอร่อยดี สถานที่บรรยากาศดี ขนมจากบ้านขนมลุงยังอร่อยเหมือนเดิม ต้องขอขอบคุณ ภาควิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ มหาวิทยาลัยสงขลานครินทร์ ที่เป็นสปอนเซอร์รายใหญ่ให้เรามาแล้ว 3 ปี Jaideawhosting 3 ปี บ้านขนมลุง 3 ปี Foobarsystem 2 ปี Sparkbit 2 ปี Tyro Bike  Joy Print และพี่เอ้ จาก Tuber ที่ให้เรายืมสถานที่ดีๆ ในการจัดงาน ผมหวังว่า BarCamp Songkhla จะใหญ่ขึ้นและมีคุณภาพมากขึ้นเทียบเท่า BarCamp BKK ได้สักวันนึง :D

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

ใช้ Watchdog ช่วยทำ TDD สำหรับ C++ ด้วย Gtest และ CMake

เห็นคนรู้จักหลายๆ คนทำ TDD กัน เลยอยากทำบาง โดยมากมักใช้ Watchr เพื่อช่วนในการรัน Test Case ทันทีที่บันทึกไฟล์ เห็นแล้วสะดวกดี แต่พอดีเขียน Ruby ไม่เป็นเลยมากหาไลบราลีภาษา Python แทน ก็ไปเจอ Watchdog อาศัยแรงของตั้วเลยได้ Python script อย่างง่ายมาเล่น TDD สำหรับ Python กัน

วันนี้อยากเอามันมาใช้กับ C++ บ้างเล่นเอาเหนื่อยเหมือนกันกว่าจะเอา Python script ของตั้วมาใช้กับ C++ ซึ่งจากที่ดูๆ มา Google Test กับ CMake น่าจะตอบโจทย์ TDD ได้ระดับนึ่ง แต่ต้องอาศัยการจัดรูปแบบของไดเร็กทอรีเข้าร่วมด้วย ตอนนี้สคริปต์ยังมีการกำหนดหลายๆ อย่างตายตัวอยู่มาก อาจจะยังไม่เรียบร้อยดีเท่าที่ควร

หน้าตาไดเร็กทอรีประมาณนี้

.
├── src
│   └── xxx
│       └── xxx.cpp
├── tests
│   ├── CMakeLists.txt
│   ├── external
│   │   └── gtest
│   │       └── CMakeLists.txt
│   └── units
│       └── xxx
│           └── test_xxx.cpp
├── cpp-testrunner
│
└── CMakeLists.txt

สำหรับไดเร็กทอรีโปรเจคจะประกอบไปด้วย src tests CmakeLists.txt และ cpp-testrunner
  • src ใช้เก็บซอร์ซโค้ดของโปรแกรม
  • tests ใช้เก็บ Test Case ต่างๆ
  • CMakeLists.txt เป็น CMake หลักของโปรเจค
  • cpp_testrunner คือสคริปต์ที่เอามาช่วยรัน Test Case
นอกจากนี้ยังมี tests/CMakeLists.txt และ tests/external/gtest/CMakeLists.txt สองไฟล์นี้ทำหน้าที่สำหรับคอมไฟล์ Test ให้กับโปรแกรม โดยที่ tests/CMakeLists.txt จะเป็นส่วนหลักในการคอมไพล์และจะเรียก tests/external/gtest/CMakeLists.txt เพื่อคอมไพล์ไลบรารี Gtest อีกทีนึง นั้นก็หมายความว่า เครื่องที่จะรันจะต้องติดตั้งเพกเกจ libgtest-dev ไว้แล้ว โดยตัวอย่างการเขียน CMake ทั้งหมดกับ Gtest ได้มาจาก google-test-examples

สำหรับส่วนของการเขียน Test จะต้องสร้าง Unit Test ไฟล์ไว้ใน tests/units และมีได้เร็กทอรีที่ล้อกับ src ดังตัวอย่าง src/xxx/xxx.cpp จะต้องสร้าง Unit Test ไฟล์ไว้ที่ tests/units/xxx/test_xxx.cpp ใช้ test_ นำหน้าที่ไฟล์ สำหรับ cpp-testrunner หน้าตาจะเหมือนด้านล่าง ใช้ Python3 นะครับ


#!/usr/bin/env python
import os
import sys
import time
import re
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
 


def when_file_changed(filename):
    def projectname():
        """
            Projectname from name of current directory ('.')
            if there are dash '-' in its name replace to underscore '_'
        """
        return os.path.abspath(".").rsplit("/", 1)[1]
 
    def get_test_cases(filename):     
        test_case = []
        try:
            with open(test_file(filename), 'r') as f:
                src = f.read()
                test_case = list(set(re.findall('TEST\s*\((.*),', src)))
        except:
            pass

        return test_case
    
    def test_file(filename):
        basename = os.path.basename(filename)
        if not basename.startswith("test_"):
            filename = filename.replace("src", "tests/units")
            filename = filename.replace(basename, "test_" + basename)
        return filename

    def make_test_runner():
        build_test_path = os.path.abspath(".")+'/build-test'
        test_path = os.path.abspath(".")+'/tests'
        os.system("cmake -B{build_test_path} -H{test_path}".format(build_test_path=build_test_path, test_path=test_path))
        os.system("make -C {build_test_path}".format(build_test_path=build_test_path))
            
 
    cls()
    print(os.path.abspath(filename))
    make_test_runner()

    # extract testcase

    test_cases = get_test_cases(test_file(filename))
    if len(test_cases) == 0:
        print('There are no unit tests, skip test running')
        return

    cmd = 'build-test/'+projectname()+'-test'\
            + ' --gtest_filter='+'.*:'.join(test_cases)+'.*'
    
    print(cmd)
    os.system(cmd)
 
 
def cls():
    os.system('cls' if os.name == 'nt' else 'clear')
 
 
class ModifiedHandler(PatternMatchingEventHandler):
    patterns = ['*.cpp', '*.hpp', '*cc', '*.h']  # Monitor only matched patterns
    def on_created(self, event):
        """" For Vim :w - not modify that deleted and created file instead. """       
        if '/build-test/' in event.src_path:
            return

        when_file_changed(event.src_path)
 
 
if __name__ == '__main__':
    args = sys.argv[1:]

    path = args[1] if args else '.'
    build_path = path + '/build-test'
    if not os.path.exists(build_path):
        os.mkdir(build_path)

    event_handler = ModifiedHandler()
    observer = Observer()
    observer.schedule(event_handler,
                      path=args[1] if args else '.', recursive=True)
    observer.start()
 
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

ไฟล์ tests/CMakeLists.txt
cmake_minimum_required(VERSION 2.8.8)

set(PROJECT_NAME HelloGtest)
set(PROJECT_TEST_NAME ${PROJECT_NAME}-test)
project(${PROJECT_NAME} C CXX)


set(EXT_PROJECTS_DIR ${PROJECT_SOURCE_DIR}/external)
add_subdirectory(${EXT_PROJECTS_DIR}/gtest)

link_libraries(
)

file(GLOB_RECURSE ${PROJECT_NAME}_CXX_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../src/*.cpp")
file(GLOB_RECURSE ${PROJECT_NAME}_CXX_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "test*.cpp")

# remove main function file from test
list(REMOVE_ITEM ${PROJECT_NAME}_CXX_SRC ${CMAKE_CURRENT_SOURCE_DIR} "../src/main.cpp")

# complier
set (CMAKE_CXX_COMPILER g++)
add_definitions(-std=c++1y -pthread)
set (CMAKE_VERBOSE_MAKEFILE TRUE)

set (CMAKE_CXX_FLAGS_DEBUG, "-g -Wall")
set (CMAKE_CXX_FLAGS "-Wall")

include_directories ("${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/../src"  "${PROJECT_SOURCE_DIR}/../tests")


add_executable (${PROJECT_TEST_NAME} ${${PROJECT_NAME}_CXX_TESTS} ${${PROJECT_NAME}_CXX_SRC})
# add_executable (${PROJECT_TEST_NAME} ${${PROJECT_NAME}_CXX_SRC})
add_dependencies(${PROJECT_TEST_NAME} googletest)
target_link_libraries (${PROJECT_TEST_NAME} 
    ${GTEST_LIBS_DIR}/libgtest.a
    ${GTEST_LIBS_DIR}/libgtest_main.a
    pthread
)

ไฟล์ tests/external/gtest/CMakeLists.txt
cmake_minimum_required(VERSION 2.8.8)
project(gtest_builder C CXX)
include(ExternalProject)

ExternalProject_Add(googletest
    SOURCE_DIR /usr/src/gtest
    CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
               -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
               -DCMAKE_CXX_FLAGS=${MSVC_COMPILER_DEFS}
               -Dgtest_force_shared_crt=ON
     PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
# Disable install step
    INSTALL_COMMAND ""
)

# Specify include dir
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIRS ${source_dir}/include PARENT_SCOPE)

# Specify MainTest's link libraries
ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBS_DIR ${binary_dir} PARENT_SCOPE)

เวลาใช้งานก็แค่ รัน cpp-testrunner ทิ้งไว้ ทุกครั้งที่มีการบันทึกไฟล์ สคลิปต์ จะรัน cmake และ make ให้อัตโนมัติ พร้อมกับรัน Test Case ของไฟล์นั้นให้เลย 

วันจันทร์ที่ 10 กุมภาพันธ์ พ.ศ. 2557

Barcamp Songkhla III

หลังจากจบงานก็ควรเขียน blog เป็นที่ระลึกตามธรรมเนียม สำหรับงานครั้งนี้เป็นคนร่วมงานปล่อยให้น้องที่ภาควิชาดำเนินงานกันไป :D สำหรับคนสนใจงานครั้งที่แล้วสามารถอ่านเพิ่มเติมได้ที่ มอง Barcamp Songkhla II

พูดอะไรในงาน Barcamp Songkhla III
สำหรับครั้งนี้ได้เตรียมหัวข้อแบบจัดเต็ม 3 session ดังนี้
  • Python for Scientific Computing โดยร่วมพูดกับ @ibotdotout @superizer เนื้อหาเเป็นการแนะนำการใช้งาน Python สำหรับการประมวลผลทางวิทยาศาสตร์ โดยเน้นไปที่ NumPy SciPy SymPy OpenCV เนื้อหาไม่ได้เจาะจงอะไรเป็นพิเศษเน้นไปที่แนะนำให้รู้จักเสียมากกว่า แล้วมีกรณีศึกษาให้ดูในตอนท้ายด้วยเล็กน้อย สำหรับเซสชันนี้ได้รับความสนใจอยู่พอสมควร
  • C++11/14: a Review เซสชันนี้เป็นการบอกคร่าวๆ ว่า C++11/14 มีอะไรน่าสนใจบ้าง โดยร่วมพูดกับ @superizer เซสชันนี้มีคนสนใจมากเป็นพิเศษ 2 คน :D อาจเป็นเพราะว่าไม่ค่อยมีคนสนใจ C++ มากแล้วก็ได้ T__T 
  • เรียน "ธรรมะ" จากชีวิตโปรแกรมเมอร์ เป็นการแนะนำธรรมะที่เคยเรียนรู้มาแล้วตอนมัธยมโดยอธิบายให้เข้ากับการเป็นโปรแกรมเมอร์ว่าเหตุใด ทำไม อย่างไร เราถึงได้ทุกข์ แล้วแก้มันอย่างไรโดยใช้วิธีที่องค์สมเด็จพระสัมมาสัมพุทธเจ้าแนะนำไว้ เซสชันนี้คนเยอะกว่า C++11
สไลด์โหลดได้จากลิงค์ตามหัวข้อนะครับ นอกจากนี้ยังมีหัวข้อต่างๆ ที่น่าสนใจอีกมาก ทั้งที่ได้เข้าฟัง และไม่ได้เข้าฟัง เช่น 
  • การถ่ายภาพโดยโปรแกรมเมอร์ โดย @maykungth 
  • เปลี่ยนเวลาว่างให้เป็นเงินด้วย Amazon โดย @dizzizdi 
  • ADS-B Flight Tracking โดย boto 
  • How to be Linux System Admin และ Cloud Computing Inside the Structure โดย @icez
  • AngularJS โดย Aj. Suthon 
  • Hacked by 1Bytes the Internet Worm/Trojan โดย BR1GH7N4RY
  • ทายนิสัยจาก Facebook โดย @makissy
  • Test Driven Development (TDD) โดย @sansarun_s
  • การพัฒนา Desktop Application ด้วย Gt webkit โดย @Yoschanin_s
  • Chromecast with node.js and raspberry pi โดย @nolifelover
  • etc.
บรรยากาศงานเป็นอย่างไร
ส่วนบรรยากาศของงานในปีนี้ถือว่าดีกว่าทุกปีที่ผ่านมา เพราะคนเยอะมากๆ :D รู้สักว่าคึกคัก อีกทั้งยังมีน้องๆ ม. ปลายเขามาร่วมสัมผัสงานด้วย ถือว่าเป็นโอกาศที่ดีสำหรับการพัฒนาตัวเอง \o/ แต่ก็ยังมีส่วนที่น่าจะต้องปรับปรุงอยู่บ้างคือ หัวข้อที่เตรียมมานำเสนอยังน้อยไป เมื่อเทียบกับจำนวนคน ซึ่งก็มีหลายคนที่พูดไป 2 เซสชันเลยทีเดียว ต้องขอขอบคุณหลายๆ ท่านเหล่านั้นเป็นอย่างมาก โดยมากมักพูดว่าขอมาเก็บความรู้ แต่จากความเข้าใจของผมเองแล้วงาน BarCamp นอกจากมาเก็บความรู้แล้ว เราควรบอกให้คนอื่นรู้บ้างว่าเรารู้อะไรบ้าง จะได้ร่วมกันแลกเปลี่ยนสิ่งที่เราคิดอยู่ว่ามันมีอะไรน่าสนใจกับคนอื่นบ้าง อีกอย่างนึงคือคนที่ลงทะเบียนแล้วไม่มา อยากบอกให้เขาเหล่านั้นทราบว่า การจัดงานมันเปลืองทรัพยากร แน่นอนว่าไม่มีใครบังคับ แต่ด้วยงานลักษณะนี้หากมีคนต้องการเข้าร่วมมากกว่าจำนวนที่รับได้ จะเป็นการกันที่คนอื่นโดยไม่จำเป็น ถือว่าเป็นคนความไม่รับผิดชอบอย่างรุ่นแรง หากว่าติดธุระสำคัญจริงๆ อันนี้ไม่ว่ากัน ถึงกระนั้นก็ยังมีคนที่ไม่ได้ลงทะเบียนแล้วมาร่วมงานด้วย อันนี้ชื่นชมจากใจจริง :D

ส่งท้าย
อยากจะบอกว่า อาหารอร่อยมาก :D ขนมเยอะดี กินกันอิ่มมากๆ ต้องขอขอบคุณทีมงานทุกคนร่วมไปถึงผู้ให้การสนับสนุนทุกๆ ท่านเป็นอย่างสูง และอยากให้ปีหน้าจัดอีกนะครับ \o/

วันจันทร์ที่ 24 มิถุนายน พ.ศ. 2556

เด็กน้อยหลงทาง

เด็กน้อยนายหนึ่งได้กล่าวไว้ว่า
ตอนนี้ผมหลงทาง ไม่รู้จะเดินไปทางไหนจิงๆ แค่ก้าวเท้าผมยังไม่รู้เลยว่าจะก้าวเท้าซ้ายหรือขวาก่อนดี อาจจะเปนเพราะผมเดินทางไม่เก่ง ไม่ชำนาญเส้น ที่สำคัญผมอ่านแผนที่ไม่ออก ผมมีผู้นำทางที่คอยบอกบริเวณที่หมายให้กับผม แต่ผมก็ยังเดินไปไม่ได้ แน่นอนว่าผมไม่ใช่คนตาบอด การที่จะให้ใครจูงผมไปยังเป้าหมายคงไม่ใช่เรื่องดีนัก ผมเริ่มเข้าใจกับคำว่ามืดแปดด้านมากขึ้นในตอนนี้ ผมคงให้สัณญาไม่ได้ว่าผมจะไปถึงเป้าหมาย แต่อย่างน้อยในตอนนี้ผมก็ได้รู้ว่าระหว่างทางมันยากลำบากแค่ไหนและก็หวังอยู่ลึกๆว่า... ผมคงไปถึงจุดหมาย แม้มันจะถึงโดยไม่สวัสดิภาพก็ตามTT #ให้ตายเถอะ Project
ที่มา facebook ของเจ้าเด็กน้อย

พี่จะบอกเจ้าเด็กน้อยว่า

เจ้าเด็กน้อยหลงทางกลางแสงดาว
แต่ละก้าวจะย่างยังหวั่นไหว
ถึงดาราบอกทางยังหวั่นใจ
หนทางใด คือมรรคา หายากจริง

เจ้าเด็กน้อยเจ้าเคยหวนไปคิด
ถึงชีวิตที่ผ่านพ้นทุกสรรพสิ่ง
เจ้าเคยเตรียม ใจกาย ไว้พักพิง
พร้อมแอบอิง ประสบการณ์ แล้วหรือยัง

เจ้าเตรียมกาย เผชิญโลกมากเพียงใด
เจ้าเตรียมใจ ทุกข์ยาก พร้อมพลาดพลั้ง
เตรียมสมอง เตรียมปัญญา เตรียมพลัง
ลดอคติ ชิงชัง จะเป็นไร

จงรู้จักเริ่มต้นที่จะคิด
ถูกหรือผิด พลาดพลั้ง ยังแก้ได้
หากไม่เริ่ม ไม่ล้ม ไม่แก้ไข
ขวากหนามใหญ่ คงอับจน พ้นปัญญา

ดีแล้วหนาที่รู้ยังอ่อนด้อย
จงอย่าคอย ให้ใคร แก้ปัญหา
จงพากเพียร เรียนรู้ พัฒนา
จะได้มาซึ่งเสบียงไว้เลี้ยงตน

แสงดาว ในที่มืด ส่องสว่าง
ยังนำทาง ให้ผู้คน ไม่สับสน
จงพินิจดาราให้แยบยล
จะรู้หนทางเดินทางต่อไป

วันอังคารที่ 30 เมษายน พ.ศ. 2556

ผ่านไปแล้วหนึ่งอาทิตย์ แก้โจทย์นี้ไม่ได้สักที

ให้โจทย์เขียนโปรแกรมไปกับเด็กคนนึง ให้เขียนด้วย Python 3
โจทย์
บางส่วนของโค้ด Python
A = [random.randint(1, 150) for i in range(0,100)]
หาค่าเฉลี่ยของสมาชิกของ A ที่ละ 10 ค่า ให้อยู่ในรูปของลิสท์

ผ่านไปแล้วหนึ่งอาทิตย์ แก้โจทย์นี้ไม่ได้สักที เลยแอบเอามาเฉลยไว้ :D

import random
A = [random.randint(1, 150) for i in range(0,100)]

length = 10
average = [sum(A[a:a+length]) / len(A[a:a+length]) for a in range(0, len(A), length)]

print(average)

โจทย์นี้อาจจะยากสำหรับผู้เริ่มต้นเรียนโปรแกรมิ่ง แต่สำหรับนักศึกษาสายคอมพิวเตอร์ในระดับมหาวิทยาลัย โจทย์นี้น่าจะเป็นเรื่องง่ายมาก แทบจะไม่ต้องใช้ความรู้มากมายในการเขียนเลย เพียงแค่ลงมือทำเท่านั้น ไม่รู้ว่าป่านนี้จะเขียนได้ยัง !!_ _ ไม่ต้องการให้เขียนได้โค้ดแบบนี้ แค่คำตอบเหมือนก็ดีใจแล้ว
เศร้าจริง.... เด็กไทย

วันพุธที่ 17 เมษายน พ.ศ. 2556

ด้วยระลึกถึงคุณย่า บันทึกจากความทรงจำ

บันทึกนี้เขียนขึ้นเพื่อบันทึกความทรงจำของผมที่มีต่อคุณย่าที่ล่วงลับไปแล้วอย่างไม่มีวันหวนคืน คุณย่าเปรียบเหมือนฟางเส้นสุดท้ายที่ร้อยครอบครัวใหญ่ของเราเอาไว้ไม่ให้แตกแยก หลังจากที่เสียคุณปู่ไปเมื่อ 23 ปีก่อน
เนื่องจากบริเวณจังหวัดกระบี่ ตรัง พังงา ภูเก็ต มีชาวจีนอาศัยอยู่มาก แต่มักจะเป็นชาวจีนที่อพยพมาไทยนานแล้ว จากการการสังเกตของผม ชาวจีนแถบนี้โดยมากน่าจะเป็นชาวเปอรานากัน หรือชาวจีนที่อพยพมาจากจีนแล้วตั้งถิ่นฐานอยู่ในแหลมลายูหรืออินโดนีเซีย แล้วหลังจากนั้นจึงอพยพมาอาศัยต่อที่ประเทศไทย จากการบอกเล่าของคุณแม่ ก๋งเคยเล่าให้ฟังว่าตอนยังเด็กเคยแจวเรือจ้างอยู่ที่ปีนัง คุณย่าเคยเล่าว่าเป็นชาวฮกเกี้ยน อีกทั้วจากรูปวาดคุณย่าทวดที่มีการเกล้ามวยผม สวมเสื้อคอลึก ส่วนทางบ้านมีการใช้คำเรียกจีนผสมไทยถิ่นใต้อยู่มาก ผู้หญิงทุกคนนิยมสวมผ้าปาเต๊ะ เสื้อลูกไม้ (เสื้อฉลุลายดอกไม้) อาหารการกินเป็นแบบชาวไทยถิ่นใต้ทุกประการ (กินน้ำพริก แกงส้มเก่งกันทุกคน ยกเว้นก๋ง :D) อีกทั้งก๋งเกิดที่ดินแดนแถบนี้ไม่ได้เดินทางมาจากเมืองจีน (บางทีเรียก เตี่ยต่อเตี่ย คือ ทวดมาจากจีน ส่วนสถานที่เกิดไม่แน่ใจว่าเป็นปีนังหรือไทย) มีศาลเจ้า แต่นิยมไปวัดเถราวาท จากสภาพการแล้วผมจึงสันนิษฐานออกมาเป็นเช่นนั้น

ลำดับญาติ

เนื่องจากทางบ้านมีคำเรียกขานในหมู่ญาติๆ ที่ผิดแผกออกจากคำเรียกลำดับญาติในหมู่ชาวจีนที่คุ้นเคย โดยเป็นคำเรียกแบบจีนสำเนียงไทยถิ่นใต้ โดยมากน่าจะเป็นภาษาฮกเกี้ยน (ภาษาไทยบ้าบ๋าภูเก็ต) หรือเป็นคำไทยถิ่นใต้ในแถบนี้ก็ยังไม่แน่ใจนัก จึงอยากบันทึกไว้สักเล็กน้อย เนื่องคนที่เกิดในรุ่นหลังๆ จะไม่เรียกแบบนี้กันแล้ว นิยมเรียกเป็น พี่ ป้า น้า อา แทน

ฝั่งพ่อ
  • ปู่ เรียก ก้อง
  • ย่า เรียก ละหมา
  • พ่อ เรียก เตี่ย รุ่นหลังนิยมเรียก ป๋า หรือ ปาป๊า แทน
  • แม่ เรียก แม่ หรือ มะ (น่าจะเป็นไทยมุสลิม) อาจจะมีคำเรียกอื่นที่เป็นคำจีนกว่านี้แต่ไม่เคยได้ยิน
  • ลุง เรียก แปะ
  • ภรรยาลุง เรียก ฮุม
  • อา เรียก เจ็ก เช็ค
  • ภรรยาอา เรียก ฉิ๋ม จิ๋ม แล้วแต่บ้าน
  • ป้า หรือ อาหญิง เรียก ก้อ
  • สามีป้า เรียก ติ่ว ทิ่ว หรือ ก้อทิ่ว
  • พี่ชาย เรียก โก้ โข ตามด้วยชื่อ
  • พี่สาว เรียก จี ฉี ฉา ตามด้วยชื่อ
  • พี่สะใภ้ เรียก โส 
ฝั่งแม่
  • ตา เรียก ก้อง
  • ยาย เรียก ยาย
  • น้าชาย เรียก กู่ หรือ คู้ 
  • น้าสะใภ้ เรียก คิ้ม กิ่ม
  • น้าหญิง ป้าหญิง เรียก อี๋
นอกจากนี้อาจจะมีชื่อเรียกอีกแต่ผมไม่ค่อยได้เรียก เลยบันทึกไว้แค่นี้ก่อน นอกจากนี้ยังมีข้นสูงขึ้น เช่น
  • ทวดชาย เรียก ก้องจ้อ ก้องโฉ
  • ทวดหญิง เรียก เล่าจ้อ เล่าโฉ
  • ฝ่ายชายที่มีลำดับเดียวกับก๋ง จะเรียกตาม พ่อแล้วลงท้ายด้วยก้อง เช่น น้องชายก๋ง เรียก เจ็กก้อง พี่ชายก๋ง เรียก แปะก้อง แต่โดยมาก ก้อง แล้วตามด้วยชื่อแทน
  • ฝ่ายหญิงที่มีลำดับเดียวกับก๋ง จะเรียกตาม พ่อแล้วลงท้ายด้วยโป๋ เช่น พี่สาวก๋ง จะเรียกว่า ก้อโป๋ พี่สะใภ้ก๋ง จะเรียก ฮุมโป๋ น้องสะใภ้ก๋ง จะเรียก ฉิมโป๋
อาจมีคำเรียกเป็นลำดับเหมือนภาษาจีนทั่วไป เช่น ตั๋ว ยี่ ซา นอกจากนี้ยังมีคำเรียกอื่นที่ไม่อยู่ในลำดับญาติที่ผมเรียกบ่อยๆ อาจจะเป็นคำภาษาถิ่นใต้ก็ได้ อันนี้ยังไม่แน่ใจ
  • ผู้ชายที่มีรุ่นราวคราวเดียวกับพ่อหรือแม่ เรียก แด้
  • ผู้หญิงที่มีรุ่นราวคราวเดียวกับพ่อหรือแม่ เรียก โบ๋ว
คำพูดของคนแถบนี้ปนไปมาระหว่างไทยจีน มีการสืบทอบแบบรุ่นต่อรุ่น หากขาดรุ่นไปก็เรียกไม่ถูก วัฒนธรรมก็ผสมผสานกัน จนอาจเห็นคนไทยไปเชงเม้ง คนจีนทำบุญเดือนสิบเป็นเรื่องปรกติ

นามสกุล

ส่วนเรื่องนามสกุลนั้น คุณแม่เล่าให้ฟังว่า ตอนก๋งไปแจ้งนามสกุลกับนายอำเภอ ก็ไม่รู้ว่าจะใช้ว่าอะไร เนื่องจากเป็นคนจีนจึงใช้แซ่ โดยมีชื่อแซ่ว่า แซ่ลิ่ม แต่การจะใช้แซ่ในไทยนั้นก็อาจจะไม่สะดวกกับการติดต่อราชการ เลยเปลี่ยนเป็นนามสกุลไทยเสีย นายอำเภอเลยถามว่าที่บ้านประกอบอาชีพอะไร ก๋งบอกว่า ทำนา เลยเป็นที่มาของนามสุกล ลิ่มนา (นายอำเภอตั้งให้) การตั้งชื่อนามสกุลในสมัยนั้นคงเป็นเรื่องที่น่าปวดหัวของนายอำเภอยุคนั้นไม่มากก็น้อย :D นามสกุลลักษณะนี้จึงมีแยะในแถบนี้เช่น ลูกหลี ลูกเหล็ม ลิ่มซิ่ว ยาเขียว ค้าของ คิดรอบ เป็นต้น ส่วนนามสกุลที่เป็นญาติๆ กันกับนามสกุลลิ่มนา จากคำบอกเล่า ก็เช่น ลิ่มซิ่ว คิดรอบ ลูกหลี (แซ่ลิ่ม แซ่หลี) ส่วนจะญาติกันมาตั้งแต่เมื่อไหร่นั้นก็ยากที่จะรู้ได้เพราะคนที่รู้เรื่อง ตอนนี้ก็มีอายุมากจนจำไม่ได้ หรือล้มหายตายจากกันไปหมดแล้ว จะรู้ว่าเป็นญาติก็จากคำบอกเล่าเท่านั้น

ไว้ทุกข์

คุณย่าของผม ท่านมีวาสนาแม้ตอนที่จากไป ท่านยังไปในวัยอันควร คืออยู่ในวัยสูงอายุ เวลาอันควรคือท่านได้ล้มป่วยให้ลูกหลานปรนนิบัติเลี้ยงดูอยู่ระยะหนึ่ง เหมือนให้ทำใจไว้ก่อน กาลอันควรคือท่านจากไปเมื่อวันที่ 28 เมษายน ซึ่งเป็นช่วงเทศกาลเชงเม้ง ทำให้คนสนิทมิตรรักที่อยู่ต่างแดน กลับมาไหว้หลุมศพบรรพบุรุษได้มาร่วมงานศพคุณย่าด้วย อาการอันควรคือท่านเหมือนหลับไปอย่างสงบ ไม่มีแม้แต่คำบอกลา เหมือนท่านไม่ห่วงอะไรแล้ว การจัดการศพท่านก็ได้เตรียมตัวไว้นานแล้ว ตั้งแต่ซื้อโลงหัวหมู (โลงจีน) ท่านได้สั่งไว้ว่าอย่าเผากลัวร้อน :D แต่ผมเข้าใจว่าท่านอยากไปอยู่ข้างๆ ก๋งมากว่าจึงได้สั่งไว้อย่างนั้น เตรียมรูปถ่ายตั้งหน้าศพไว้อย่างเรียบร้อย ไม่ต้องลำบากลูกหลาน โชคดีอย่างหนึ่งของผม คือผมกลับบ้านทันก่อนที่ญาติจะตอกฝาโลง ผมจึงได้เห็นหน้าคุณย่าครั้งสุดท้าย
ถ้ายังไม่จัดดอกไม้ก็จะมีผ้าห่มโลง โลงแบบนี้เรียกโลงหัวหมู
การจัดการศพผมเคยบันทึกไว้แล้วครั้งนึงตอนงานศพคุณอา บันทึกการจัดงานศพ: พิธีทั่วไป และ  บันทึกการจัดงานศพ: พิธีฌาปนกิจศพ ครั้งที่แล้วเป็นพิธีจีนแบบไทย คือใส่โลงเผา แต่คราวนี้นี้จะเป็นพีธีจีนลดรูป เนื่องจากใส่โลงหัวหมูนั้นเอง ส่วนอะไรที่บันทึกไปแล้วก็จะไม่ขอเขียนอีก
ตอนที่ผมไปถึงบ้าน ร่างคุณย่าได้ถูกบรรจุไว้ในโลงเรียบร้อยแล้ว คุณย่านอนโดยมีผ้าห่มห่มร่างและมีเสื้อผ้าอีกชุดนึงอยู่ในโลงด้วย ในกระเป๋าคุณย่ามีเงินที่ลูกๆ หลานๆ ใส่ให้ ทั้งเหรียญ ทั้งแบงค์ตามสมควร มีการประพรมน้ำหอมและทาแป้งให้คุณย่าเป็นครั้งสุดท้าย ร่างคุณย่าห่อหุ้มด้วยผ้ายางอีกทีนึงกันน้ำเหลืองไหล เนื่องจากคุณย่าไม่ได้นอนห้องแอร์นั้นเอง โลงจะต้องยาด้วยชันอย่างดีด้วยเช่นกัน คุณลุงเป็นคนยาชันโลงเอง หลังจากนั้นจะตอกตะปู โดยที่การตอกตะปูจะต้องรองด้วย กระดาษเงินกระดาษทองก่อนเสมอ บรรจุร่างคุณย่าเสร็จก็มีพิธีพระโดยทั่วไปปรกติ 
เนื่องจากครั้งนี้การบรรจุร่างคุณย่าในโลงจีนจึงต้องมีเครื่องไว้ทุกข์ ก็คือผ้าติดแขน โดยแต่ละคนจะใช้สีต่างกัน จริงๆ แล้วลูกชายจะต้องเป็นปลอกแขน แต่ในงานนี้ได้ลดรูปเป็นแค่ผ้าชิ้นสี่เหลี่ยมแทน
ติดแขนไว้ทุกข์
  • ผ้าดิบหุ้มผ้ากระสอบ (ที่บ้านเรียกผ้าสิหริง) ใช้กับ ลูกชายทั้งหมด ลูกสะใภ้ ลูกสาวที่ยังไม่แต่งงาน หลานชายที่เกิดจากลูกชาย (เรียกหลานใน) หลานสาวที่เกิดจากลูกชายและยังไม่แต่งงาน
  • ผ้าดิบ ใช้กับ ลูกสาวที่แต่งงานแล้ว
  • ผ้าขาว ผ้าแดง ใช้กับ ลูกเขย
  • ผ้าขาว ผ้าดำ ใช้กับ หลานที่เหลือทั้งหมด ไม่ว่าจะหลานที่เกิดจากลูก หรือหลานที่เกิดจากพี่น้องอื่นๆ รวมถึง พี่ๆ น้องๆ
  • ผ้าขาว ผ้าน้ำเงิน ใช้กับ เหลน ยกเว้นเหลนที่เกิดจากหลายชาย จะใช้ขาวดำแทน
การติดเข็มกลัดจะกลัดข้างขวาถ้าผู้ตายเป็นผู้หญิง และมีได้แดงหากพ่อหรือแม่ของผู้ไว้ทุกข์ยังไม่เสียชีวิต การติดลักษณะนี้อาจเป็นเพราะว่า สมัยก่อนไม่มีรูปถ่าย คนที่มาร่วมงานก็จะรู้ทั้นทีว่าใครเป็นใคร ผู้เสียชีวิตเป็นหญิงหรือชาย จะต้องเรียกว่าอะไรก็ดูได้จากแขนเสื้อนั่นเอง ส่วนงานนี้ลูกหลานจะใส่เสื้อเป็นผ้าดิบตลอดงาน และจนกว่าจะครบร้อยวัน งานนี้ทำให้ผมรู้ว่าผมมีญาติเยอะจริงๆ เข็มกลัด 5 พวง พวกละ 10 อันยังไม่พอ แต่ผมรู้จักบ้าง ไม่รู้จักบ้าง ออกไปทางไม่รู้จักเสียมากกว่า :D
นอกจากเครื่องไว้ทุกข์แล้วคนตายมีอายุมากกว่าจะใส่ผ้าดิบ ไม่ตัดผม ไม่ตัดเล็บ ไม่โกนหนวด ไม่โกนเครา ไม่แต่งหน้า ไม่หวีผม ไม่ประพรมของหอม เสื้อผ้าไม่รีด และอื่นๆ อีกมากมาย น่าจะเป็นเพราะว่าเมื่อมีงานศพจะมีกิจกรรมอื่นๆ ให้ทำอีกมากมาย การละกิจกรรมเหล่านี้ไว้ยกเป็นข้อห้ามจะทำให้ไม่ขัดเขินเวลาต้อนรับแขกนั้นเอง แต่ปีนี้ก็ 2556 เข้าไปแล้ว บางอย่างเลยละไว้ เช่น การรีดผ้า เป็นต้น ส่วนเสื้อผ้าจะต้องดำสนิท หรือขาวเท่านั้น ไม่เว้นแต่ชุดชั้นใน ผ้าข้าวม้า ผ้าถุงอาบน้ำ ผ้าเช็ดตัวก็ต้องเป็นขาว หรือดำ เทาๆ บ้างไม่เป็นไร ในวันแรกที่คุณย่าเสีย ออกจะโกลาหลพอสมควร ก็เรื่องชุดชั้นในนี่แหละ :D
ระหว่างงานศพจะมีการไหว้ศพย่อย คือ 3 วัน และ 7 วัน (เรียกว่าใส่ 3 ใส่ 7) โดยจัด ไก่หนึ่งตัว หมูสามชั้น ไข่เป็ด ไข่ไก่ หมีเหลืองผัด อาหารตามคุณย่าชอบ นอกจากนี้มีการถวายสังฆทานตามเวลาอำนวย ปรกติแล้วที่บ้านจะไว้ศพไม่นาน แต่งานคุณย่าไว้ศพเก้าวัน เนื่องจากติดเทศกาลเชงเม้งนั่นเอง การฝั่งศพในวันดังกล่าวอาจไม่สะดวก (ได้ยินว่างานศพก๋งไว้ 12 วัน เนื่องจากติดเทศกาลตรุษจีน) ตลอดงานหากมีการทำบุญเจ้าภาพจะมีของชำรวยเล็กๆ น้อยๆ (ทุกชิ้นจะมีด้ายแดงติดอยู่ด้วยถือว่าเป็นอั่งเปา) และบัตรขอบคุณ (บัตรบอกรายละเอียดผู้ตายเล็กๆ น้อย เช่น อายุ เสียชีวิตเมื่อไหร่ กำหนดสวดพระอภิธรรม กำหนดวันฌาปนกิจศพ ที่่สำคัญคือคำขอบคุณ และมีด้ายแดงติดอยู่ด้วย) ตอบแทนนอกเหนือจากการเลี้ยงอาหาร อาหารว่าง ชา กาแฟ แล้ว

เคลื่อนศพ

ก่อนเคลื่อนศพโดยปรกติแล้วชาวจีนจะไหว้ครั้งสุดท้าย เป็นการไหว้ชุดใหญ่ ครั้งนี้จะไหว้เครื่องคู่ ทุกอย่างจะจัดเป็นคู่ๆ ยกเว้นข้าวห้าถ้วย เหล้าห้าจอก ชาสามจอก สิ่งที่ขาดไม่ได้ไม่ว่าจะครั้งใหนคือ หมี่เหลืองผัด และหมู่ย่าง ถึงแม้ว่ากระบี่จะไม่ใช่เมืองหมูย่างแต่ก็ใช้หมูย่างเป็นเครื่องเซ่นเป็นประจำ :D ถึงเวลาไหว้ ลูกหลานก็จะไหว้แยกออกเป็นคณะๆ เมื่อไหว้เสร็จจะต้องไปนั่งข้างโลงจนกว่าจะจบพิธี
เครื่องเซ่นไหว้
  • ลูกๆ ทั้งหมด รวมลูกสะใภ้ ไม่รวมเขย
  • เขย
  • หลานทั้งหมด จริงๆ แล้วจะต้องแยกเหลน ออก แต่เนื่องจากว่า เด็กๆ ยังเล็กเลยไหว้พร้อมกันเสียเลย
  • หลานเขย
  • ญาติฝั่งคุณปู่
  • ญาติฝั่งคุณย่า
  • คนสนิท มิตรรัก
เห็นจากเข็มกลัดที่ติดแขนไว้ทุกข์ว่าเยอะแล้ว เห็นตอนไหว้ศพญาติฝั่งปู่ฝั่งย่ามีเยอะกว่านั้นอีกมาก !!_ _
ตามประเพณีการเคลื่อนศพออกจากบ้านไปสุสานจะใช้วิธีหามลูกหลานที่เดินตามจะต้องไม่สวมรองเท้า ใส่ผ้าดิบเต็มชุด หลานนอกใส่ครึ่งท่อนคือเสื้อเป็นผ้าดิบผ้าถุงดำหรือกางเกงดำตามสมควร แต่เนื่องจากงานคุณย่าเป็นช่วงหน้าร้อนอีกทั้งลูกๆ ก็อยู่ในวัยสูงอายุ หากเดินจริงอาจเป็นลมกันเป็นแถวแน่นอน เลยเปลี่ยนไปใช้วิธีบรรทุกรถแทน ก่อนศพเคลื่อนออกจากบ้านจะจุดประทัดและกรวดน้ำก่อน 

ฝังศพ

ก็เป็นไปตามพิธีฌาปนกิจปรกติ มีการถวายเครื่องนำทาง (เครื่องสังฆทานชุดใหญ่) ถวายผ้าบังสุกุล แต่เปลี่ยนจากเผามาเป็นฝั่งแทน ก่อนฝั่งจะมีการโปรยทานก่อน จุดประทัด จึงเริ่มหย่อนโลงลงหลุมจัดตำแหน่งโลงให้เหมาะสม จากนั้นจะเริ่มโปรยดินกลบ โดยที่ลูกชายคนแรกจะเริ่มเดินเวียนซ้ายรอบหลุมศพพร้อมกับโปรยดิน โปรยเหรียญเงิน ลูกๆ หลานๆ เหลนๆ และญาติๆ จะเดินตามกันเป็นแถว เวียนสามรอบ แล้วจึงคุ้นดินถมอย่างจริงจัง สภาพหลุมก็ขุดเป็นรูปทรงสี่เหลี่ยมผืนผ้า มีการทำคันดินเป็นหมอนรองโลงสองอัน อีกอย่างนึงครั้งนี้ได้ขุดไปเจอโลงของก๋ง ซึ่งยังอยู่ในสภาพดีมากทีเดียว หลังจากก๋งได้จากพวกเราไปเมื่อ 23 ปีก่อน ฝังและพูนดินเสร็จก็เป็นอันว่าก๋งและย่าได้อยู่ด้วยกันแล้ว
เหรียญโปรทานหรือกำพรึก
หลังจากฝังเสร็จก็มีการเซ่นไหว้เป็นครั้งสุดท้าย มีการจุดประทัดกรวดน้ำตามพิธี จึงแล้วเสร็จ หากใครจะปลดเครื่องไว้ทุกข์ ก็จะวางไว้หน้ากระถางธูปที่นี่เลย ใครจะผลัดผ้าดิบเป็นผ้าดำปรกติ ก็จะปลดเหมือนกัน โดยมากเป็นญาติห่างๆ ที่ไม่สะดวกมาทำบุญร้อยวัน ลูก หลาน เหลนที่ยังเรียนหนังสืออยู่ หรือทำงานที่ยากต่อการไว้ทุกข์ ก็จะปลดที่นี้ โดยมากจะผลัดเป็นผ้าดำ ผ้าขาวยกเว้นหลาน เหลน หรือญาติห่างๆ จะผลัดผ้าสีเลย
ปลดเครื่องไว้ทุกข์
เมื่อเสร็จกิจกรรมตามพิธีแล้ว ก็จะออกปากชวนคุณย่ากลับบ้าน โดยนำกระถางธูป รูปภาพ ตะเกียงลูกไก่กลับไปเซ่นไหว้ต่อที่บ้าน เมื่อถึงบ้านจะต้องล้างเท้าก่อน แล้วจึงก้าวข้ามกองไฟ ใครถือกระถามธูป ตะเกียง รูปภาพ ก็จะเดินหันหลังเข้าบ้าน จุดธูปบอกคุณย่าอีกครั้ง จึงแล้วเสร็จ ตลอดงานจะใช้ธูปไหว้สองดอก ซึ่งอาจแตกต่างกับการไหว้ศพคนไทยปรกติ

เซ่นไหว้ร้อยวัน

เนื่องจากตามประเพณีจะมีการเซ่นไหว้ผู้ตายก่อนหนึ่งร้อยวัน จะไม่มีการดับตะเกียงลูกไก่ และมีการตั้งน้ำตั้งข้าวเหมือนกับที่ผู้ตายยังมีชีวิตอยู่ จนกว่าจะครบร้อยวัน รวมทั้งมีการเซ่นไหว้เล็ก เหมือนกับตอนตั้งศพ ทุกๆ เจ็ดวัน จนครบเจ็ดครั้ง หรือ 49 วัน ก็จะหยุดไหว้เล็ก แล้วไปเซ่นไหว้หนึ่งร้อยวันทีเดียว และจะมีการทำบุญร้อยวัน (รวมทั้งหมดนี่ที่บ้านเรียกว่าใส่ร้อย) อีกครั้งหนึ่ง

ระลึกถึงคุณย่า

คุณย่าเป็นภาพของอดีตที่ผมจำได้เม่นกว่าก๋งมากนัก เนื่องจากคุณย่ามีอายุถึง 95 ปี ส่วนก๋งนั้นจากไม่เมื่อผมอายุน้อย คุณย่าเป็นคนเก่ง คนสู้ชีวิต เลี้ยงลูกหกคนได้สบาย ถึงแม้ว่าจะลำบากแต่ก็ไม่อด ท่านทำงานทุกอย่าง ไม่ว่าจะเป็นทำนา นวดข้าวเอง บูชาแม่โพสพ ขายขนมจีน เย็บตับจาก กวนนุ่น โกยบ่อเกรอะ ไล่ควาย ยอนไข่มดแดง แกงแลน ไม่ว่าของแปลกที่ใช้ทำกับข้าวจะเป็นอะไรท่านแกงได้หมด และรู้ว่าต้องทำอย่างไร อาจเป็นเพราะว่าสมัยก่อนยังยากจน ไม่ค่อยจะมีอะไรกิน (รวมไปถึงมีเงินก็ไม่รู้จะซื้อจากไหนด้วย) เป็นคนอยู่ไม่นิ่ง มีเวลาท่านจะเข้าป่า หาผักหวานป่า หาหน่อไม้ หรืออะไรที่กินได้ เลี้ยงวัว เลี้ยงหมู เลี้ยงไก่ จนครั้งนึงเคยขายวัวจนหมดฝูงแต่ก็เว้นไว้ให้คุณย่าหนึงตัว ไว้จูงไปกินหญ้าเพือออกกำลังกาย :D คุณย่าเป็นคนใจดีกับหลานๆ และชอบทำบุญ เวลาลาคุณย่าไปใหน ท่านจะให้พรว่า "ขอให้โชคดี โชคดี ทำงานให้เป็นเจ้าคนนายคน" ซึ่งพรประโยคนี้ดีมาก เนื่องจากสอนให้ทำงานมากกว่าพึ่งพาโชคแต่เพียงอย่างเดียว ภาพเหล่านั้นยังเป็นภาพจำของผมเสมอ

งานศพคุณย่า ทำให้ผมรู้ว่า สังคมบ้านนอกยังไม่ต้องใช้จ่ายค่าดำเนินงานในลักษณะนี้มากนัก แค่รู้ว่ามีงานศพไม่จำเป็นที่เจ้าภาพออกบัตรเชิญหรือบอกกล่าว ชาวบ้านที่เป็นมิตรก็พร้อมจะมาช่วยเหลือทันที ไม่ว่าจะเป็นทำกับข้าว ยกหลา (ประกอบเต้น) เสริฟอาหาร ล้างจาน พร้อมใจกันทำไม่ต้องบอก ได้ยินว่าก่อนที่ร่างคุณย่าจะมาถึงบ้าน ที่บ้านก็ยกหลาเรียบร้อยแล้ว มีโต๊ะเก้าอี้พร้อมเพรียง พร้อมจะจัดงาน เมื่อโลงพ้นเขตบ้านเต้นและเครื่องครัวทั้งหมดก็โดนขนกลับหมด มีเหลือให้เจ้าภาพได้จัดการต่อไม่มากนัก เคยมีคนกล่าวไว้ว่าเจ้าภาพมีหน้าทีเดียวคือร้องไห้ :D ของกำนัลที่นิยมให้ตอบแทนคนช่วยงานมีเพียงแค่เป็นผ้าขนหนู หรือผู้ชุบ (ผ้าขาวม้า) ผูกด้ายแดงเท่านัน คนครัวส่วนใหญ่ซึ่งเป็นหญิงจะได้ผ้าขนหนู คนยกหลา ยกโต๊ะ ยกโลง ส่วนใหญ่จะเป็นผู้ชายจะได้ผ้าชุบ ทุกคนต่างเต็มใจช่วยเหลือ ส่วนหนึ่งอาจจะมาจากเครือญาติที่เหนียวแน่นด้วย จากการสังเกตแล้วไม่ค่อยจะมีเด็กรุ่นหนุ่มสาวมาช่วยงานมากนัก คงมีแต่รุ่นน้า รุ่นอา เท่านั้น ทั้งนี้อาจเป็นเพราะไปเรียนหนังสือ หรือทำงานที่ต่างแดนก็เป็นได้ ความร่วมมือร่วมแรงร่วมใจเช่นนี้อาจมีน้อยลงหรือจางหายไปไม่มีให้เห็นอีกแล้วในอนาคตก็เป็นได้

สุดท้ายนี้ ด้วยบุญ ด้วยกุศลที่คุณย่าทำมาจากอดีต ขอจงเป็นแรงหนุนนำให้คุณย่าไปสู่ภพภูมิที่ดีด้วยเทอญ

ด้วยรักและอาลัยยิ่ง