Saturday, June 15, 2013

What Makes A Good Teacher?

Marie F. Hassett, Ph.D.
Bricolage, Inc., Jamaica Plain, MA
I have been teaching for the last ten years. During that time, I have workedin public schools, universities, extracurricular programs for K-12, adult basic literacy, and adult enrichment classes. My youngest student was a 6 year-old budding actress in a town-sponsored arts enrichment program for elementary students; my oldest, a Jamaican immigrant, a grandmother beginning at the age of 63 to learn how to read. I've taught honors students in a college humanities program, and severely handicapped youth in a public high school.
The breadth of my experience has enriched my teaching life, but left me without a luxury some of my colleagues enjoy-the sense, as I walk into a new class, for a new term, that I know what my students will need, and how best to share it with them. This is not to say that I've been tossed blind into the classroom. In most cases, I've had enough prep time to gather what seem like appropriate materials, and find out something about the students I'll be working with. What I have not had is the critical mass of sameness that accrues to the teacher who stays in the same setting, at the same level, for many years in a row. I cannot assume that what worked last semester will work this time.
As a result of my ever-changing context, I've spent a lot of time thinking about the craft and practice of teaching, as separate from course content, age of students, size of class, or institutional setting. Everywhere I go, I meet exemplary teachers, and I've been interested in figuring out what makes them so good. What I've discovered is the inherent sameness of good teachers, regardless of the substantial differences between them in terms of style, personality, goals, and pattern of interaction with students. I would go so far as to say that good teachers, in all settings and at all levels, have more in common with each other than any of them may have with their colleagues in comparable positions.
In order to understand the bold statement above, try the following exercise. Sit back, close your eyes, and bring to mind the three best teachers you ever had. Try to remember what they were like-how they looked, talked and acted, what their classrooms and/or offices were like, how they made you feel as their student. When you're satisfied that you've gotten a good picture of who these people were, open your eyes, and consider the words of educator and philosopher Parker Palmer:
Good teaching isn't about technique. I've asked students around the country to describe their good teachers to me. Some of them describe people who lecture all the time, some of them describe people who do little other than facilitate group process, and others describe everything in between. But all of them describe people who have some sort of connective capacity, who connect themselves to their students, their students to each other, and everyone to the subject being studied. (1999, p. 27)
Do you recognize your best teachers in this description? When we talk about the quality of someone's teaching, we address issues of technique, content, and presentation. But we all know people who have tremendous knowledge but fail to communicate it: people who have, on paper, a great lesson, but whose students are bored or frustrated. When we're being honest, we admit that good teaching often has less to do with our knowledge and skills than with our attitude towards our students, our subject, and our work.
The rest of this article will address some of the characteristics that good teachers exhibit. It is not meant to be all encompassing or definitive; many excellent teachers may possess only some of these traits, and consider others not mentioned to be just as valuable. The characteristics detailed here may be viewed simply as a selection of tools that allow teachers to create and sustain connectivity in their classrooms.
Good teachers:
• have a sense of purpose;
• have expectations of success for all students;
• tolerate ambiguity;
• demonstrate a willingness to adapt and change to meet student needs;
• are comfortable with not knowing;
reflect on their work;
• learn from a variety of models;
enjoy their work and their students.


Good teachers have a sense of purpose.
You can't be good in a generic sense; you have to be good for something. As a teacher, this means that you know what your students expect, and you make plans to meet those expectations. You, too, have expectations about what happens in your classroom, based on the goals you're trying to achieve. If you want to prepare your students for employment, you expect punctuality and good attendance. If you teach a GED class, you spend time explaining the format of the test and helping students to improve their test-taking skills. And if you want your students to become better, more involved readers, you allow time for reading and provide access to books.
Good teachers have expectations of success for all students.
This is the great paradox of teaching. If we base our self-evaluation purely on the success of our students, we'll be disappointed. At all levels, but especially in adult education, there are simply too many factors in students'lives for a teacher to be able to guarantee success to all. At the same time, if we give up on our students, adopting a fatalistic, "it's out of my hands" attitude, students will sense our lack of commitment and tune out. The happy medium can be achieved with a simple question: Did I do everything that I could in this class, this time, to meet the needs of all my students, assuming that complete success was possible? As long as you can answer in the affirmative, you're creating a climate for success.
Good teachers know how to live with ambiguity.
One of the greatest challenges of teaching stems from the lack of immediate, accurate feedback. The student who walks out of your classroom tonight shaking his head and muttering under his breath about algebra may burst into class tomorrow proclaiming his triumph over math, and thanking you for the previous lesson. There is no way to predict precisely what the long-term results of our work will be. But if we have a sense of purpose informing our choice of strategies and materials, and we try to cultivate expectations of success for all our students, we will be less likely to dwell on that unpredictability, choosing instead to focus on what we can control, and trusting that thoughtful preparation makes good outcomes more likely than bad ones.

Good teachers adapt and change to meet student needs.
Can we really claim to have taught a class in geography if no one learned any of the concepts in the lesson from our presentation? If none of our students ever pick up a book outside of the classroom, have we really taught them to be better readers? We don't always think about these issues, but they are at the heart of effective teaching. A great lesson plan and a great lesson are two entirely different things; it's nice when one follows the other, but we all know that it doesn't always work out that way. We teach so that students will learn, and when learning doesn't happen, we need to be willing to devise new strategies, think in new ways, and generally do anything possible to revive the learning process. It's wonderful to have a good methodology, but it's better to have students engaged in good learning.
Good teachers are reflective.
This may be the only infallible, absolute characteristic of all good teachers, because without it, none of the other traits we've discussed can fully mature. Good teachers routinely think about and reflect on their classes, their students, their methods, and their materials. They compare and contrast, draw parallels and distinctions, review, remove and restore. Failing to observe what happens in our classes on a daily basis disconnects us from the teaching and learning process, because it's impossible to create connectivity if you've disconnected yourself.
Good teachers are comfortable with not knowing.
If we reflect honestly and thoughtfully on what happens in our classes, we will often find dilemmas we cannot immediately resolve, questions we cannot answer. In his Letters to a Young Poet, Rainer Maria Rilke suggests that his correspondent, "try to love the questions themselves as if they were locked rooms or books written in a very foreign language…. Live the questions now. Perhaps then, someday far in the future, you will gradually, without even noticing it, live your way into the answer" (1986, pp. 34-35). In the same way, our teaching benefits if we can live for a little while with a question, think and observe, and let an answer develop in response to the specific situation we face.
Good teachers had good role models.
Think back again to your three best teachers. How has your own teaching been shaped by their practices, consciously or unconsciously? Think also of the worst teacher you ever had. Are there things you absolutely will not do because you remember how devastating they were to you or your classmates? We learn to teach gradually, and absorb ideas and practices from a variety of sources. How many movies have you seen that include a teacher as a character, and how might those films have contributed to your practice? We are not always aware of the influences on our teaching, good and bad; reflecting on the different models of teaching we've acquired, and looking at how we acquired them, makes us better able to adapt and change to suit new challenges.

Good teachers enjoy their work and their students.
This may seem obvious, but it's easy to lose sight of its importance. Teachers who enjoy their work and their students are motivated, energized, and creative. The opposite of enjoyment is burnout-the state where no one and nothing can spark any interest. Notice, too, that enjoying your work and enjoying your students may be two different things. Focusing too much on content may make students feel extraneous, misunderstood, or left out. Focusing exclusively on students, without an eye to content, may make students feel understood and appreciated, but may not help them to achieve their educational goals as quickly as they'd like. Achieving a balance between the two extremes takes time and attention; it demands that we observe closely, evaluate carefully, and act on our findings.
I would like to conclude with a poem by Lao-Tzu, the Chinese scholar to whom the Tao Te Ching is attributed. I have carried a copy of this poem with me for many years, and I find its message both helpful and challenging. It reminds us that good teaching is not a static state, but a constant process. We have new opportunities to become better teachers every day; good teachers are the ones who seize more opportunities than they miss.
Some say that my teaching is nonsense.
Others call it lofty but impractical.
But to those who have looked inside themselves,
this nonsense makes perfect sense.
And to those who put it into practice,
this loftiness has roots that go deep.

I have just three things to teach:
simplicity, patience, compassion.
Simple in actions and thoughts,
you return to the source of being.
Patient with both friends and enemies,
you accord with the way things are.
Compassionate toward yourself,
You reconcile all being in the world. (1989, 17)


Works Cited
Mitchell, Stephen, ed. (1989). The Enlightened Heart. NY: Harper & Row.
_____, trans. (1986). Letters to a Young Poet, by Rainer Maria Rilke. NY: Vintage Books.
Palmer, Parker. (1999). "The Grace of Great Things: Reclaiming the Sacred in Knowing, Teaching, and Learning." In The Heart of Knowing: Spirituality in Education. Ed. Stephen Glazer. NY: Jeremy P. Tarcher/Putnam.
Originally published in Adventures in Assessment,
Volume 12 (Winter 2000),
SABES/World Education, Boston, MA, Copyright 2000.
Funding support for the publication of this document on the Web provided in part by the Ohio State Literacy Resource Center as part of the LINCS Assessment Special Collection.

Wednesday, May 29, 2013

Using Celery to Handle Asynchronous Processes

This article continues the series on building a continuous deployment environment using Python and Django.
Those of you following along, now have the tools to setup a Python/Django project, fully test it, and deploy it. Today we will be discussing the Celery package, which is an open source asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.
Simply put, processes can be run asynchronously and distributed, instead of by the main app. This allows complex calculation, heavy data processing, or third-party services to all be run without blocking the main Django/Python app. And when run on a remote server, without using resources of the main Django app. Celery is a Python project, but there is an app, django-celery, which plugs into Django.

Getting ready

To install Celery, enter your virtualenv and call:

$ pip install celery

Install a technology to manage the Celery queue (RabbitMQ is recommended). Full RabbitMQ installation instructions are available at http://www.rabbitmq.com/install.html.
To install RabbitMQ on debian/ubuntu:

$ sudo apt-get install rabbitmq-server


RabbitMQ will start automatically upon installation. To start/stop RabbitMQ manually on debina/ubuntu:

$ invoke-rc.d rabbitmq-server start
$ invoke-rc.d rabbitmq-server stop


On most systems the log file for RabbitMQ can be found at /var/log/rabbitmq/rabbit.log.
To install RabbitMQ on OSX (this will take a long time):


$ sudo brew install rabbitmq

RabbitMQ will be installed to /usr/local/sbin, so add this directory to your PATH, if you haven't already done so.To start/stop RabbitMQ manually on OSX:



$ sudo rabbitmq-server
$ sudo rabbitmqctl stop
To install Celery for Django:

 
$ pip install django-celery

How do it…

Setup RabbitMQ for use with Celery:
$ sudo rabbitmqctl add_user {CELERY_USER} {CELERY_USER_PASS}
$ sudo rabbitmqctl add_vhost {CELERY_VHOST}
$ sudo rabbitmqctl set_permissions -p {CELERY_VHOST} {CELERY_USER} ".*" ".*" ".*"




Don't use any periods in the {CELERY_VHOST} or Celery won't be able to connect to RabbitMQ. If the server cannot connect on OSX, see Broker Installation for additional setup information.
Create your first task, task.py:






from celery.task import task
@task
def add(x, y):
    return x + y
Create a configuration file to run your Celery task, celeryconfig.py:








BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "{CELERY_USER}"
BROKER_PASSWORD = "{CELERY_USER_PASS}"
BROKER_VHOST = "{CELERY_VHOST}"
CELERY_RESULT_BACKEND = "amqp"
CELERY_IMPORTS = ("tasks", )

If RabbitMQ is running remotely, change localhost to the name of the remote server.
Now to test, start Celery (it will print to the console):


$ celeryd --loglevel=INF$ O
In another terminal, open the Python shell and run:








from tasks import add
from celery.execute import send_task
result = add.apply_async(args=[2, 2], kwargs={})
print result.get()
result = send_task('task.add', [3, 3])
print result.get()
result = add.delay(4, 4)
You should see something like the following in the terminal window running Celery:







[2011-08-31 23:43:44,242: INFO/MainProcess] Got task from broker: tasks.add[f5f5ee81-fef5-46d2-87de-0da005d588d0]
[2011-08-31 23:43:44,294: INFO/MainProcess] Task tasks.add[f5f5ee81-fef5-46d2-87de-0da005d588d0] succeeded in 0.0111658573151s: 4
[2011-08-31 23:43:44,301: INFO/MainProcess] Got task from broker: tasks.add[cd2de0d1-35ad-4d7a-8212-47e800cd85bc]
[2011-08-31 23:43:44,298: INFO/MainProcess] Task tasks.add[cd2de0d1-35ad-4d7a-8212-47e800cd85bc] succeeded in 0.0115258693695s: 6
[2011-08-31 23:43:44,301: INFO/MainProcess] Got task from broker: tasks.add[cd2de0d1-35ad-4d7a-8212-47e900cd85bc]
[2011-08-31 23:43:44,329: INFO/MainProcess] Task tasks.add[cd2de0d1-35ad-4d7a-8212-47e900cd85bc] succeeded in 0.0115258693695s: 8
To run celery as a daemon process on debian/ubuntu, install https://github.com/ask/celery/tree/master/contrib/generic-init.d/, and run:
?

$ /etc/init.d/celeryd {start|stop|restart|status}
To configure your process, edit /etc/default/celeryd:


# Name of nodes to start # here we have a single node CELERYD_NODES="w1" # or we could have three nodes: #CELERYD_NODES="w1 w2 w3"
# Where to chdir at start. CELERYD_CHDIR="/opt/Myproject/"
# Extra arguments to celeryd CELERYD_OPTS="-time-limit=300 -concurrency=8"
# Name of the celery config module. CELERY_CONFIG_MODULE="celeryconfig"
# %n will be replaced with the nodename. CELERYD_LOG_FILE="/var/log/celery/%n.log" CELERYD_PID_FILE="/var/run/celery/%n.pid"
# Workers should run as an unprivileged user. CELERYD_USER="celery" CELERYD_GROUP="celery"
For deamon scripts on other operating systems and for more information on configuration, see Celery Daemonizing.

Django-Celery

If you use django-celery, you won't need the celeryconfig.py file, as the Celery configuration will live in the project's settings.py.
To start add djcelery to INSTALLED_APPS, then add the following to settings.py:


import djcelery
djcelery.setup_loader()
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERY_RESULT_BACKEND = "amqp"
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "{CELERY_USER}"
BROKER_PASSWORD = "{CELERY_USER_PASS}"
BROKER_VHOST = "{CELERY_VHOST}"
To create the necessary database tables:

 
$ python manage.py syncdb
For those using mod_wsgi, add the following to your *.wsgi file:



import os
os.environ["CELERY_LOADER"] = "django"
Celery will automatically look for files named tasks.py in other installed apps and process them accordingly. Another great use for Celery are periodic tasks:



from datetime import timedelta
from celery.decorators import periodic_task
@periodic_task(run_every=timedelta(days=1))
def update_users():
    aggregate_user_data() # not defined here, just an example
There is some additional information available at http://ask.github.com/django-celery/.
Lastly, start a process to snapshot the workers, so you can use Django to monitor celery:


$ nohup python manage.py celerycam &
More information on monitoring is available at Celery Monitoring.

How it works…

Celery uses tasks that are executed concurrently on one or more workers. Tasks can execute asynchronously or synchronously (result = task.get() or task.wait()). A third party service is used for managing queueing of tasks and storing of task results. RabbitMQ is recommended for the queue, although many DB technologies are supported, and I prefer AMQP or Redis for the results backend.
To create a Celery task, first create a file named tasks.py and then add task functions there. Decorate each function that will be explicitly called with @task and functions that execute periodically with @periodic_task(run_every=timedelta({FREQUENCY})). Tasks, including periodic tasks, can be called explicity using mytask.delay(*args, **kwargs). This returns a result object, which can be used to lock the current thread until the task is completed using result.wait() or response = result.get().
The Celery worker process will log all activity, so monitor it for errors (usually /var/logs/celeryd.log). Try to make sure task functions gracefully handle errors, so that no data is ever lost.
The celery-django package manges your Celery commands and configuration, adds an admin tool, and discovers tasks.py automatically in all your apps. To monitor the Celery workers via Django start the celerycam process, which will take periodic snapshots of the workers and write to the djcelery_taskstate table.
This should provide enough information for you to start using Celery in your own projects. Feel free to leave any questions you may have.

There’s more…

Much of this article was inspired by the Celery Documentation. I recommend starting there is you have any questions. For additional information:
This post is an acknowledgement to: http://mattsnider.com/using-celery-to-handle-asynchronous-processes/


Monday, March 4, 2013

Django with MySql set up (on Ubuntu)

This post describes the installing Django with MySql set up in a succinct way. 
Install Django and MySql
Note: Switch to root in the terminal and do the following:
 
$ sudo apt-get install python-django
$ sudo apt-get install mysql-server
$ sudo apt-get install python-mysqldb
MySql database and use Set up:
Note, use the password you entered when installing MySql

$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.51a-3ubuntu5.1 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE DATABASE django_db;
Query OK, 1 row affected (0.01 sec)

mysql> GRANT ALL ON django_db.* TO 'djangouser'@'localhost' IDENTIFIED BY 'mypassword';
Query OK, 0 rows affected (0.03 sec)

mysql> quit
Bye
Create a Django Project
$ django-admin startproject mysite
Edit the Django database settings
Edit mysite/settings.py:
DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'django_db'             # Or path to database file if using sqlite3.
DATABASE_USER = 'djangouser'             # Not used with sqlite3.
DATABASE_PASSWORD = 'mypassword'         # Not used with sqlite3.
DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
Use Django to create the database tables
$ cd mysite
$ python manage.py syncdb
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_content_type
Creating table django_session
Creating table django_site

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'sofeng'):    
E-mail address: sofeng@email.com
Password: 
Password (again): 
Superuser created successfully.
Installing index for auth.Message model
Installing index for auth.Permission model
Loading 'initial_data' fixtures...
No fixtures found.
Run the development server
$ python manage.py runserver
Validating models...
0 errors found.

Django version 0.96.1, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[30/Jul/2008 16:37:23] "GET / HTTP/1.1" 404 2053
Point your browser at http://127.0.0.1:8000 and you should see the Django It worked! page.

one more online source: Baby Steps with Django - part 2 database setup