Thứ Năm, 22 tháng 5, 2014

Chấm điểm

Sưu tầm được bài viết "Chấm điểm" của tác giả Nguyễn Huỳnh Mai thấy đúng ý nghĩ của mình nên chép về đây để làm tài liệu tham khảo. Đúng là phải tận dụng việc chấm điểm như là công cụ để học hỏi chứ không phải là công cụ thể hiện quyền lực của thầy/cô giáo.

Bàn về cách thức “chấm điểm” học trò

(Dân trí) - Sau 30 năm đi dạy và nghiên cứu về giáo dục, tôi vẫn chưa tìm được một phương pháp chấm điểm trò một cách thật hữu hiệu, công bằng và khách quan.

Tôi vẫn thường kể thí dụ sau đây cho sinh viên: đưa một bài luận văn của một thí sinh Tú Tài ở Pháp cho ba giám khảo khác nhau với những tiêu chỉ chấm điểm rỏ ràng : ba giám khảo này sẽ cho ba điểm khác nhau. Cũng với một bài luận văn, đưa cho một giám khảo ở hai lúc khác nhau, giám khảo này sẽ cho hai điểm khác nhau.

Vai trò chấm điểm của thầy?
Đứng trên bục giảng, đối diện với những chờ đợi của học trò, người đi dạy có rất nhiều việc phải làm, có rất nhiều trách nhiệm chứ không phải chỉ truyền dạy kiến thức. Trong tất cả những việc phải làm, riêng bản thân tôi rất “kỵ” vai trò chấm điểm, phê phán hay xếp hạng học trò. Tôi vẫn nghĩ rằng trường học là nơi đào tạo, là nơi để trẻ học làm người, là nơi để các em phát triển khả năng và là nơi để các em sống hạnh phúc nữa. Chứ không phải là nơi để bị hay được phê phán, thưởng hay phạt.

Ý kiến của bạn về vấn đề này xin gửi đến Diễn đàn Dân trí qua địa chỉ e-mail:thaolam@dantri.com.vn
Đồng thời tôi cũng biết rằng xã hội không phải là một thiên đường, là một cái gì lý tưởng, chỉ có trong truyện thần tiên. Trường học cũng phải có ít nhất một phần tối thiểu luật lệ và chế tài. Để có thể hoạt động bình thường và cũng để chuẩn bị cho các em ra đời, đối mặt với xã hội. Có những học trò cần phải thi mới học.

“Cần phải thi mới học” - Không phải bẩm sinh các em có nhu cầu này - Có thể vì văn hóa xã hội đã gây nên tình trạng ấy : vì xã hội xem trọng bằng cấp nên người đi học phải thi đổ. Cứu cánh của sự học thành ra “để thi đổ”  và trường học trở nên lò luyện thi ... 

Nhưng ngay ở Bỉ, cũng có nhiều học trò chỉ học vì phải thi. Thế nhưng từ từ, một số nhà sư phạm bắt đầu lên tiếng phân tích mọi mặt của vấn đề thi cử, đánh giá học trò, đánh giá quá trình học và đồng thời đề nghị vài phương pháp nhỏ để việc “chấm điểm” học trò được thực hiện hoàn chỉnh hơn.

Từ những thập niên 60, nhiều tiếng nói đã  đề nghị về những phương thức để chấm điểm học trò mà nổi tiếng nhất có lẻ là những bài thi trắc nghiệm (QCM)  được xem như là một hình thức dễ áp dụng, học trò không cần khả năng viết bài, có thể bao phủ hết chương trình của môn học lại dễ chấm, sáng sủa, ít nhầm lẫn...

Thế nhưng việc chấm điểm học trò không phải chỉ là công cụ chấm điểm (thực ra mỗi hình thức - câu hỏi mở, trắc nghiệm, thi viết, thi vấn đáp, ... - đều có cái khả thi và cái bất khả thi) mà sâu xa hơn nhiều. Có những điểm làm cho học trò sung sướng nhận bằng cấp, cũng như có những điểm ám ảnh người đi học trong suốt quảng đời còn lại (tiếng Pháp gọi là névrose d'échec – bệnh ám ảnh thất bại?). Dĩ nhiên đấy là hai thái cực.

Chấm điểm cái gì ?
Một số đông người đi dạy chỉ chấm điểm khả năng lặp lại (savoir-restituer) vốn hiểu biết đã thu thập được thầy truyền cho. Nói một cách quá đáng, tôi thường bảo rằng học trò của tôi không phải là những con vẹt, chúng không phải lặp lại những gì tôi đã giảng.

Các giáo sư, nhất là giáo sư các môn khoa học như Toán, Vật lý, ... chấm điểm khả năng ứng dụng (savoir-appliquer)  qua các bài tập, ...

Cao hơn tí, nhiều đồng nghiệp tôi đòi ở học trò khả năng làm việc (savoir-faire)  tức là thêm vào đó sự sáng tạo, dấu ấn riêng của các em khi đứng trước một hoàn cảnh phức tạp hơn để đi đến giải pháp thích hợp (chẳng hạn học nhạc pháp lý thuyết, sau đó sáng tác).

Học là để làm người, có học thì có thể có xu hướng làm người trọn vẹn hơn (nhờ những môn như triết học, chính trị học, kinh tế, xã hội học nếu chấm điểm được khả năng đó (savoir-être)  thì rất hay.

Những điều nói trên có vẻ lý thuyết nhưng chúng thể hiện được sự đa dạng của những gì học trò lĩnh hội được ở trường. Đa dạng đến nổi mà người đi dạy phải biết những giới hạn của cái điểm mình cho học trò.

Chấm điểm chỉ là một dấu ghi nhận, có giá trị tương đối,  rằng ở khoảng thời gian nào đó, người học trò đã lĩnh hội / hay không lĩnh hội được một số hành trang hiểu biết mà thầy chờ đợi. Học trò kém một môn không có nghĩa là em ngu hay dốt.

Chấm điểm chế tài hay chấm điểm để phát triển?
Hình thức thứ nhất – chế tài – là để cho lên lớp, để cấp bằng. Chấm điểm ở cuối học trình. Sau đó trò nào đậu thì mừng với kết quả,   còn những trò khác thì không biết tại sao mình thi rớt .

Hình thức thứ hai - để phát triển - chấm điểm để thấy chỗ nào đã hiểu hết, đoạn nào đã suôn sẻ và chỗ nào chưa thấu đáo hầu làm lại, đào sâu hơn để thấu đáo. Sau khi thi, với bài thi trên tay, thầy và trò phân tích để hiểu thêm, học cách khác, thay đổi phương pháp chẳng hạn,  để kết quả tốt hơn.
Nói một cách cực đoan : nếu chỉ chấm điểm kiểu chế tài, trò nào không đủ điểm phải ngồi lại lớp, phải thi lại, ...  việc ngồi lại lớp, mất một năm, nhiều khi không có ích lợi gì vì thầy và trò vẫn không hiểu những “nguyên nhân” của bảng điểm xấu để có thể làm tốt hơn.

Đi vào cụ thể?
Tôi chưa bao giờ đề nghị từ bỏ việc chấm điểm chế tài ở cuối học trình  mặc dù hình thức này có nhiều điểm tiêu cực.

Tôi chỉ đề nghị thêm vào đó, nhiều cuộc chấm điểm trong suốt học trình để thầy và trò “nắm vững tình hình” để mà cùng đi tiếp, để có thể “trở tay” đúng lúc, tìm hình thức thay đổi khi có vấn đề. Chấm điểm và đào tạo thành “một công mà hai việc” liên đới với nhau. Thế ta sẽ tránh được tình trạng đậu hay rớt ở cuối học trình mà tất cả các trò “đều xong học trình”.

Lý thuyết có vẻ đơn giản nhưng để thực hiện được 12 năm học không có thi “tốt nghiệp” (tương đương với trung học bên nhà)  nước Bỉ đã qua một quá trình làm thử, thay đổi, ... với khả năng cung cấp không những giáo dục cưỡng bách cho tất cả đến 18 tuổi mà còn cung cấp những trường thích hợp (phổ thông, kỷ thuật hay chuyên nghề, ... ) tùy theo nhu cầu và khả năng của mỗi trò.

Việc chấm điểm trong học trình cần được thầy và trò thống nhất trong tư duy. Nếu thầy nêu rõ mục đích, chỉ tiêu của môn mình dạy, truyền cho trò những cách để đánh giá quá trình học thì cả thầy và trò đều có thể đồng trách nhiệm, một loại “khế ước” giửa thầy và trò.  Sự “được người lớn tin cậy, tín cẩn” làm trẻ “lớn” hẳn lên, cố xứng đáng niềm tin đó. Trẻ con nhờ thế có thể trưởng thành sớm hơn ta tưởng tượng, nắm vận mệnh học hành trong tay.

“Chấm điểm” trở thành, ít nhất là một phần, “tự chấm điểm” và trong chừng mực ấy, không còn là một công cụ thể hiện “quyền lực của thầy” .

Từ một chuyện chuyên thuần giáo dục, chấm điểm trò cũng là một vấn đề liên hệ đến xã hội, văn hóa và đạo đức.

Cá nhân và kinh nghiệm riêng ?
Tôi có dùng “chấm điểm-trả bài” (évaluation-restitution) cho những sinh viên năm đầu đối với những hiểu biết căn bản cần có. Trước kỳ thi, các em được chuẩn bị về hình thức các câu hỏi, những gì tôi chờ đợi, tiêu chuẩn chấm điểm, ... Những sinh viên khác, tôi dùng hình thức thi với sách và tài liệu mở (examen à livres ouverts) và cuối cùng thì tôi chấm điểm những nghiên cứu của sinh viên.
                                                           
Nguyễn Huỳnh Mai <huynhmai@poirrier.be> 

Thứ Bảy, 5 tháng 4, 2014

Nhớ

Chỉ có một người nuôi nấng, chăm lo cho ta suốt cuộc đời
Chỉ có một người thương yêu, lo lắng cho ta suốt cuộc đời
Chỉ có một một tình yêu vô điều kiện, mà ta ít khi nhận ra
... Và chỉ có một nỗi buồn, nỗi nhớ luôn theo ta suốt cuộc đời này.

Video 1. Mẹ



Video 2. Nhật ký của Mẹ


Thứ Sáu, 4 tháng 4, 2014

Mở file trong Code::Blocks

Thay đổi chương trình dùng để mở file trong Code::Blocks

Khi bạn dùng Code::Blocks mở một file có đuôi không phải là *.c, *.cpp thì Code::Block yêu cầu chọn:
- Select an external program to open it
- Open it with the associated application
- Open it inside the Code::Blocks editor


Nếu chúng ta chọn "Select an external program to open it" thì lần sau dùng Code::Blocks để mở file có đuôi đó thì Code::Blocks sẽ dùng chương trình "external" trước đó để mở file.

Nếu muốn mở file đó trong Code::Blocks ta dùng cách sau:
- Chọn Settings menu, Enviroment

- Chọn Files extension handling, Chọn đuôi trong Registered wildcards, Chọn "Open it in a Code::Blocks"


Thứ Ba, 24 tháng 9, 2013

Đường đi ngắn nhất. Thuật toán Dijkstra's với priority_queue hay set trong

Thuật toán Dijkstra 

Độ phức tạp: O(E.logV)

#include <bits/stdc++.h>
using namespace std;

const int INT_MAX = 1e9;
typedef pair<int, int> pii;

// input
vector<vector<pii> > adj;

// output
vector<int> dist, pre;

Thuật toán Dijkstra với priority_queue

void Dijkstra(int s) {
  // Khoi tao
  int n = adj.size();
  dist.assign(n, INT_MAX);
  dist[s] = 0;
  pre.assign(n, -1);

  priority_queue<pii, vector<pii> , greater<pii> > q;
  q.push(make_pair(0, s));

  // Lap
  while (!q.empty()) {
    int d = q.top().first;
    int u = q.top().second;
    q.pop();

    if (d != dist[u]) continue;

    for (int i=0; i<(int) adj[u].size(); i++) {
      int v = adj[u][i].first;
      int uv = adj[u][i].second;
      

      if (dist[v] > d+uv) {
        dist[v] = d+uv;
        pre[v] = u;

        q.push(make_pair(dist[v], v));      
      }
    }
  }
}



Thuật toán Dijkstra với set

void Dijkstra2(int s) {
  // Khoi tao
  
  int n = adj.size();  
  dist.assign(n, INT_MAX);  
  dist[s] = 0;  
  pre.assign(n, -1);  

  set<pii> q;  
  q.insert(make_pair(0, s));  

  // Lap  
  while (!q.empty()) {    
    int u = q.begin()->second;
    q.erase(q.begin()); 
   
    for (int i=0; i<(int) adj[u].size(); i++) {      
      int v = adj[u][i].first;      
      int uv = adj[u][i].second;     

      if (dist[v] > dist[u]+uv) {        
        q.erase(make_pair(dist[v], v));        
        dist[v] = ndist[u]+uv;        
        pre[v] = u;        
        q.insert(make_pair(dist[v], v));      
      }    
    }
  }
}


int main() {

  adj.resize(2);
  adj[0].push_back(make_pair(1, 10));
  adj[1].push_back(make_pair(2, -5));
  adj[0].push_back(make_pair(2, 8));

  Dijkstra(0);

  for (int i = 0; i < dist.size(); i++)  cout << dist[i] << endl;
}

CTDL Disjoint-set với rank heuristic

CẤU TRÚC DỮ LIỆU DISJOIN - SET

Ý nghĩa: cấu trúc dữ liệu Disjoin - set dùng để biểu diễn các tập hợp, mỗi tập hợp có thể có giá trị từ 0 đến n. Disjoin - set cho phép thực hiện nhanh các thao tác như: 
(1) Hợp 2 tập hợp thành một tập hợp
(2) Kiểm tra 2 phần tử có thuộc tập hợp không

Cấu trúc dữ liệu:
  • Các phần tử: có giá trị từ 0, 1, 2, ..., n
  • Các phần tử này thuộc tập hợp nào đó, nên ta quản lý tập hợp phần tử i thuộc là parent[i]. Như vậy một tập hợp là một cái cây, và gốc của cây là giá trị đại diện cho tập hợp


Như vậy, cấu disjoin set chỉ đơn giảng là một mảng parent[] của các phần tử i cho biết cha của phần tử i là ai.


Chương trình:
#include <bits/stdc++.h>
using namespace std;

const int maxn = 200000;

// Cấu trúc dữ liệu
int parent[maxn];
int n;

int rank[maxn];


void Init(int num) {
  n = num;
  fill(rank, rank + n, 0);
  for (int i = 0; i < n; i++) parent[i] = i;
}


int Root(int x) {
  return (x == parent[x]) ? x : (parent[x] = Root(parent[x]));
}


void UnionSet(int a, int b) {
  a = Root(a);
  b = Root(b);
  if (a == b) return;
  if (rank[a] < rank[b]) swap(a, b);
  if (rank[a] == rank[b]) ++rank[a];
  parent[b] = a;
}

bool IsSameSet(int a, int b) {
  a = Root(a);
  b = Root(b);

  return a==b;
}

int main() {
  Init(3);
  UnionSet(02);
  cout << (0 == Root(0)) << '\n';
  cout << (1 == Root(1)) << '\n';
  cout << (0 == Root(2)) << '\n';
}

Fenwick tree

Fenwick tree



Bài toán
Cho dãy số a=(a(1), a(2), ..., a(n)) và nhiều phép truy vấn Sum(l, r) dùng tính tổng dãy con a(l) + a(l+1) + ... + a(r) và truy vấn Update(i, x) để tăng giá trị a(i) lên x giá trị.

Giải pháp Fenwick tree

Giới thiệu:
  1. Fenwick tree hay Binary Indexed Tree (BIT) là phương pháp tiền xử lý giúp tính tổng Sum(l, r) và cập nhật Update(i, x) trên dãy số a trong thời gian O(log n). 
  2. Lịch sử: Phương pháp Fenwick tree do Pete Fenwickin đề xuất vào năm 1994.
  3. Độ phức tạp: Độ phức tạp của phép toán tính tổng dãy con và cập nhật các phần tử của mảng là O(log n)
Ý tưởng Fenwick tree:
Fenwick tree là mảng T[1...n], trong T[i] = tổng các phần tử dãy a thuộc đoạn [(i-2^k)+1, i], trong đó k là vị trí bit 1 nằm bên phải nhất của số nhị phân của biến i.


Bây giờ, chúng ta sẽ trình bày toàn bộ code của Fenwick tree:

void Update(int i, int x) {
    while (i<n) {
        T[i] += x;
        i |= (i + 1);
    }
}

int Sum(int n) {
    int res = 0;
    while (n>= 0) {
        res += data[n];
        n= (n& (n+1)) - 1;
    }
    return res;
}


Ở đây, Sum(i) trả về tổng của các phần tự từ phần tử đầu tiên đến phần tử thứ i. Việc tìm tổng của một đoạn bất kỳ có thể thực hiện bằng truy vấn Sum(right)-Sum(left-1). 


Fenwick tree chuẩn chỉ hỗ trợ cập nhật 1 phần tử tại một thời điểm. Tuy nhiên, chúng ta có thể mở rộng cho việc cập nhật cả một đoạn - câu lệnh cập nhật sẽ phát biểu thành "tăng mỗi giá trị giữa left và right một lượng giá trị". Chúng ta có thể chỉnh sửa cây cho cập nhật như thế trong thời gian O(log n):

void Update(int left, int right, int by) {
    internalUpdate(left, by, -by * (left - 1));
    internalUpdate(right, -by, by * right);
}

void InternalUpdate(int i, int mul, int add) {
    while (i<n) {
        dataMul[i] += mul;
        dataAdd[i] += add;
        i|=(i+ 1);
    }
}

int Query(int i) {
    int mul = 0;
    int add = 0;
    int start = i;
    while (i>= 0) {
        mul += dataMul[i];
        add += dataAdd[i];
        i= (i& (i+ 1)) - 1;
    }
    return mul * start + add;
}