diff options
author | hardythe1 | 2014-06-12 14:44:39 +0530 |
---|---|---|
committer | hardythe1 | 2014-06-12 14:44:39 +0530 |
commit | f4ff073c0e144546d7c205f6c99df6baed763b04 (patch) | |
tree | 3c6163a3d3aa22362ab9009ece2019e60fc267a6 /lecture_notes | |
parent | 2a0aa076b9879a71dba6235ef84efa9cd15fda80 (diff) | |
download | sees-f4ff073c0e144546d7c205f6c99df6baed763b04.tar.gz sees-f4ff073c0e144546d7c205f6c99df6baed763b04.tar.bz2 sees-f4ff073c0e144546d7c205f6c99df6baed763b04.zip |
restructuring and renaming files/directories with underscores instead of spaces & '-'
Diffstat (limited to 'lecture_notes')
75 files changed, 17047 insertions, 0 deletions
diff --git a/lecture_notes/advanced_python/arrays.rst b/lecture_notes/advanced_python/arrays.rst new file mode 100644 index 0000000..d5699ce --- /dev/null +++ b/lecture_notes/advanced_python/arrays.rst @@ -0,0 +1,736 @@ +Arrays +====== + +In this section, we shall learn about a very powerful data structure, +specially useful for scientific computations, the array. We shall look at +initialization of arrays, operations on arrays and a brief comparison with +lists. + +Arrays are homogeneous data structures, unlike lists which can be +heterogeneous. They can have only one type of data as their entries. + +Arrays of a given length are comparatively much faster in mathematical +operations than lists of the same length, because of the fact that they are +homogeneous. + +Now let us see how to create arrays. + +To create an array we will use the function ``array()``, + +:: + + a1 = array([1,2,3,4]) + +Notice that we created a one dimensional array here. Also notice that we +passed a list as an argument, to create the array. + +We create two dimensional array by converting a list of lists to an array + +:: + + a2 = array([[1,2,3,4],[5,6,7,8]]) + +A two dimensional array has been created by passing a list of lists to the +array function. + +Now let us use ``arange()`` function to create the same arrays as before. + +:: + + ar1 = arange(1, 5) + +The ``arange`` function is similar to the range function that we have already +looked at, in the basic Python section. + +To create the two dimensional array, we first obtain a 1D array with the +elements from 1 to 8 and then convert it to a 2D array. + +To obtain the 1D array, we use the ``arange`` function + +:: + ar2 = arange(1, 9) + print ar2 + +We use the shape method to change the shape of the array, into a 2D array. + +:: + + ar2.shape = 2, 4 + print ar2 + +This gives us the required array. + +Instead of passing a list to the array function, we could also pass a list +variable. For, instance + +:: + + l1 = [1,2,3,4] + a3 = array(l1) + +We used the shape method to change the shape of the array. But it can also +be used to find out the shape of an array that we have. + +:: + a1.shape + a2.shape + +As, already stated, arrays are homogeneous. Let us try to create a new +array with a mix of elements and see what happens. + +:: + + a4 = array([1,2,3,'a string']) + +We expect an error, but there wasn't one. What happened? Let's see what a4 +has. + +:: + + a4 + +There you go! The data type of the array has been set to a string of +length 8. All the elements have been implicitly type-casted as strings, +though our first three elements were meant to be integers. The dtype +specifies the data-type of the array. + +There some other special methods as well, to create special types of +arrays. We can create an 2 dimensional identity array, using the function +``identity()``. The function ``identity()`` takes an integer argument which +specifies the size of the diagonal of the array. + +:: + + identity(3) + +As you can see the identity function returned a three by three array, with +all the diagonal elements as ones and the rest of the elements as zeros. + +``zeros()`` function accepts a tuple, which is the shape of the array that +we want to create, and it generates an array with all elements as zeros. + +Let us creates an array of the order four by five with all the elements +zero. We can do it using the method zeros, :: + + zeros((4,5)) + +Notice that we passed a tuple to the function zeros. Similarly, ``ones()`` +gives us an array with all elements as ones. + +Also, ``zeros_like`` gives us an array with all elements as zeros, with a +shape similar to the array passed as the argument and the same data-type as +the argument array. + +:: + + a = zeros_like([1.5, 1, 2, 3] + print a, a.dtype + +Similarly, the function ``ones_like``. + +Let us try out some basic operations with arrays, before we end this +section. + +Let's check the value of a1, by typing it out on the interpreter. + +:: + + a1 + +``a1`` is a single dimensional array, array([1,2,3,4]). Now, try + +:: + + a1 * 2 + +We get back a new array, with all the elements multiplied by 2. Note that +the value of elements of ``a1`` remains the same. + +:: + + a1 + +Similarly we can perform addition or subtraction or division. + +:: + + a1 + 3 + a1 - 7 + a1 / 2.0 + +We can change the array, by simply assigning the newly returned array to +the old array. + +:: + + a1 = a1 + 2 + +Notice the change in elements of a1, + +:: + + a1 + +We could also do the augmented assignment, but there's a small nuance here. +For instance, + +:: + + a = arange(1, 5) + b = arange(1, 5) + + print a, a.dtype + print b, b.dtype + + a = a/2.0 + b /= 2.0 + + print a, a.dtype + print b, b.dtype + +As you can see, ``b`` doesn't have the expected result because the +augmented assignment that we are doing, is an inplace operation. Given that +arrays are optimized to be very fast, by fixing their datatype and hence +the amount of memory they can occupy, the division by a float, when +performed inplace, fails to change the dtype of the array. So, be cautious, +when using in-place assignments. + +Now let us try operations between two arrays. + +:: + + a1 + a1 + a1 * a2 + +Note that both the addition and the multiplication are element-wise. + +Accessing pieces of arrays +========================== + +Now, that we know how to create arrays, let's see how to access individual +elements of arrays, get rows and columns and other chunks of arrays using +slicing and striding. + +Let us have two arrays, A and C, as the sample arrays that we will use to +learn how to access parts of arrays. + +:: + + A = array([12, 23, 34, 45, 56]) + + C = array([[11, 12, 13, 14, 15], + [21, 22, 23, 24, 25], + [31, 32, 33, 34, 35], + [41, 42, 43, 44, 45], + [51, 52, 53, 54, 55]]) + +Let us begin with the most elementary thing, accessing individual elements. +Also, let us first do it with the one-dimensional array A, and then do the +same thing with the two-dimensional array. + +To access, the element 34 in A, we say, + +:: + + A[2] + +A of 2, note that we are using square brackets. + +Like lists, indexing starts from 0 in arrays, too. So, 34, the third +element has the index 2. + +Now, let us access the element 34 from C. To do this, we say + +:: + + C[2, 3] + +C of 2,3. + +34 is in the third row and the fourth column, and since indexing begins +from zero, the row index is 2 and column index is 3. + +Now, that we have accessed one element of the array, let us change it. We +shall change the 34 to -34 in both A and C. To do this, we simply assign +the new value after accessing the element. + +:: + + A[2] = -34 + C[2, 3] = -34 + +Now that we have accessed and changed a single element, let us access and +change more than one element at a time; first rows and then columns. + +Let us access one row of C, say the third row. We do it by saying, + +:: + + C[2] + +How do we access the last row of C? We could say, + +:: + + C[4] + +for the fifth row, or as with lists, use negative indexing and say + +:: + + C[-1] + +Now, we could change the last row into all zeros, using either + +:: + + C[-1] = [0, 0, 0, 0, 0] + +or + +:: + + C[-1] = 0 + +Now, how do we access one column of C? As with accessing individual +elements, the column is the second parameter to be specified (after the +comma). The first parameter, is replaced with a ``:``. This specifies that +we want all the elements of that dimension, instead of just one particular +element. We access the third column by + +:: + + C[:, 2] + +So, we can change the last column of C to zeroes, by + +:: + + C[:, -1] = 0 + +Since A is one dimensional, rows and columns of A don't make much sense. It +has just one row and + +:: + + A[:] + +gives the whole of A. + +Now, that we know how to access, rows and columns of an array, we shall +learn how to access other, larger pieces of an array. For this purpose, we +will be using image arrays. + +To read an image into an array, we use the ``imread`` command. We shall use +the image ``squares.png``. We shall first navigate to that path in the OS +and see what the image contains. + +Let us now read the data in ``squares.png`` into the array ``I``. + +:: + + I = imread('squares.png') + +We can see the contents of the image, using the command ``imshow``. We say, + +:: + + imshow(I) + +to see what has been read into ``I``. We do not see white and black +because, ``pylab`` has mapped white and black to different colors. This can +be changed by using a different colormap. + +To see that ``I`` is really, just an array, we say, + +:: + + I + +at the prompt, and see that an array is displayed. + +To check the dimensions of any array, we can use ``.shape``. We say + +:: + + I.shape + +to get the dimensions of the image. As we can see, ``squares.png`` has the +dimensions of 300x300. + +Our goal for now, is be to get the top-left quadrant of the image. To do +this, we need to access, a few of the rows and a few of the columns of the +array. + +To access, the third column of C, we said, ``C[:, 2]``. Essentially, we are +accessing all the rows in column three of C. Now, let us modify this to +access only the first three rows, of column three of C. +We say, + +:: + + C[0:3, 2] + +to get the elements of rows indexed from 0 to 3, 3 not included and column +indexed 2. Note that, the index before the colon is included and the index +after it is not included in the slice that we have obtained. This is very +similar to the ``range`` function, where ``range`` returns a list, in which +the upper limit or stop value is not included. + +Now, if we wish to access the elements of row with index 2, and in +columns indexed 0 to 2 (included), we say, + +:: + + C[2, 0:3] + +Note that when specifying ranges, if you are starting from the beginning or +going up-to the end, the corresponding element may be dropped. + +:: + + C[2, :3] + +also gives us the same elements, [31, 32, 33] + +Now, we are ready to obtain the top left quarter of the image. How do we go +about doing it? Since, we know the shape of the image to be 300, we know +that we need to get the first 150 rows and first 150 columns. + +:: + + I[:150, :150] + +gives us the top-left corner of the image. + +We use the ``imshow`` command to see the slice we obtained in the +form of an image and confirm. + +:: + + imshow(I[:150, :150]) + +How would we obtain the square in the center of the image? + +:: + + imshow(I[75:225, 75:225]) + +Our next goal is to compress the image, using a very simple technique to +reduce the space that the image takes on disk while not compromising too +heavily on the image quality. The idea is to drop alternate rows and +columns of the image and save it. This way we will be reducing the data to +a fourth of the original data but losing only so much of visual +information. + +We shall first learn the idea of striding using the smaller array C. +Suppose we wish to access only the odd rows and columns (first, third, +fifth). We do this by, + +:: + + C[0:5:2, 0:5:2] + +if we wish to be explicit, or simply, +:: + + C[::2, ::2] + +This is very similar to the step specified to the ``range`` function. It +specifies, the jump or step in which to move, while accessing the elements. +If no step is specified, a default value of 1 is assumed. + +:: + + C[1::2, ::2] + +gives the elements, [[21, 23, 0], [41, 43, 0]] + +Now, that we know how to stride over an array, we can drop alternate rows +and columns out of the image in I. + +:: + + I[::2, ::2] + +To see this image, we say, +:: + + imshow(I[::2, ::2]) + +This does not have much data to notice any real difference, but notice that +the scale has reduced to show that we have dropped alternate rows and +columns. If you notice carefully, you will be able to observe some blurring +near the edges. To notice this effect more clearly, increase the step to 4. + +:: + + imshow(I[::4, ::4]) + +That brings us to our discussion on accessing pieces of arrays. We shall +look at matrices, next. + +Matrices +======== + +In this course, we shall perform all matrix operations using the array +data-structure. We shall create a 2D array and treat it as a matrix. + +:: + + m1 = array([[1,2,3,4]]) + m1.shape + +As we already know, we can get a 2D array from a list of lists as well. + +:: + + l1 = [[1,2,3,4],[5,6,7,8]] + m2 = array(l1) + m3 = array([[5,6,7,8],[9,10,11,12]]) + +We can do matrix addition and subtraction as, + +:: + + m3 + m2 + +does element by element addition, thus matrix addition. + +Similarly, + +:: + + m3 - m2 + +it does matrix subtraction, that is element by element +subtraction. Now let us try, + +:: + + m3 * m2 + +Note that in arrays ``m3 * m2`` does element wise multiplication and not +matrix multiplication, + +And matrix multiplication in matrices are done using the function ``dot()`` + +:: + + dot(m3, m2) + +but for matrix multiplication, we need arrays of compatible sizes and hence +the multiplication fails, in this case. + +To see an example of matrix multiplication, we choose a proper pair. + +:: + + m1.shape + +m1 is of the shape one by four, let us create an array of the shape four by +two, + +:: + + m4 = array([[1,2],[3,4],[5,6],[7,8]]) + dot(m1, m4) + +Thus, the function ``dot()`` can be used for matrix multiplication. + +We have already seen the special functions like ``identity()``, +``zeros()``, ``ones()``, etc. to create special arrays. + +Let us now look at some Matrix specific operations. + +To find out the transpose, we use the ``.T`` method. + +:: + + print m4 + print m4.T + +Now let us try to find out the Frobenius norm of inverse of a 4 by 4 +matrix, the matrix being, + +:: + + m5 = arange(1,17).reshape(4,4) + print m5 + +The inverse of a matrix A, A raise to minus one is also called the +reciprocal matrix such that A multiplied by A inverse will give 1. + +:: + + im5 = inv(m5) + +The Frobenius norm of a matrix is defined as square root of sum of squares +of elements in the matrix. The Frobenius norm of ``im5`` can be found by, + +:: + + sqrt(sum(im5 * im5)) + +Now try to find out the infinity norm of the matrix im5. The infinity norm +is defined as the maximum value of sum of the absolute of elements in each +row. + +The solution for the problem is, + +:: + + max(sum(abs(im5), axis=1)) + +Well! to find the Frobenius norm and Infinity norm we have an even easier +method, and let us see that now. + +The norm of a matrix can be found out using the method ``norm()``. In order +to find out the Frobenius norm of the im5, we do, + +:: + + norm(im5) + +And to find out the Infinity norm of the matrix im5, we do, +:: + + norm(im5,ord=inf) + + +The determinant of a square matrix can be obtained using the function +``det()`` and the determinant of m5 by, + +:: + + det(m5) + +The eigen values and eigen vector of a square matrix can be computed +using the function ``eig()`` and ``eigvals()``. + +Let us find out the eigen values and eigen vectors of the matrix +m5. We can do it as, + +:: + + eig(m5) + + +Note that it returned a tuple of two matrices. The first element in +the tuple are the eigen values and the second element in the tuple are +the eigen vectors. Thus the eigen values are, +:: + + eig(m5)[0] + +and the eigen vectors are, + +:: + + eig(m5)[1] + +The eigen values can also be computed using the function ``eigvals()`` as, + +:: + + eigvals(m5) + + +We can also find the singular value decomposition or S V D of a matrix. + +The SVD of ``m5`` can be found by + +:: + + svd(m5) + +Notice that it returned a tuple of 3 elements. The first one U the +next one Sigma and the third one V star. + +That brings us to our discussion of matrices and operations on them. But we +shall continue to use them in the next section on Least square fit. + +Least square fit +================ + +First let us have a look at the problem. + +We have an input file generated from a simple pendulum experiment, which we +have already looked at. We shall find the least square fit of the plot +obtained by plotting l vs. t^2, where l is the length of the pendulum and t +is the corresponding time-period. + +:: + + l, t = loadtxt("/home/fossee/pendulum.txt", unpack=True) + l + t + +We can see that l and t are two sequences containing length and time values +correspondingly. + +Let us first plot l vs t^2. Type +:: + + tsq = t * t + plot(l, tsq, 'bo') + +We can see that there is a visible linear trend, but we do not get a +straight line connecting them. We shall, therefore, generate a least square +fit line. + +We are first going to generate the two matrices ``tsq`` and A, the vander +monde matrix. Then we are going to use the ``lstsq`` function to find the +values of m and c. + +Let us now generate the A matrix with l values. We shall first generate a 2 +x 90 matrix with the first row as l values and the second row as ones. Then +take the transpose of it. Type + +:: + + A = array((l, ones_like(l))) + A + +We see that we have intermediate matrix. Now we need the transpose. Type + +:: + + A = A.T + A + +Now we have both the matrices A and tsq. We only need to use the ``lstsq`` + +:: + + result = lstsq(A, tsq) + +The result is a sequence of values. The first item in this sequence, is the +matrix p i.e., the values of m and c. Hence, + +:: + + m, c = result[0] + m + c + +Now that we have m and c, we need to generate the fitted values of t^2. Type + +:: + + tsq_fit = m * l + c + plot(l, tsq, 'bo') + plot(l, tsq_fit, 'r') + +We get the least square fit of l vs t^2 + +That brings us to the end of our discussion on least square fit curve and +also our discussion of arrays. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/data/L_TSq_limited.png b/lecture_notes/advanced_python/data/L_TSq_limited.png Binary files differnew file mode 100644 index 0000000..c6e280e --- /dev/null +++ b/lecture_notes/advanced_python/data/L_TSq_limited.png diff --git a/lecture_notes/advanced_python/data/L_Tsq.png b/lecture_notes/advanced_python/data/L_Tsq.png Binary files differnew file mode 100644 index 0000000..75f2c70 --- /dev/null +++ b/lecture_notes/advanced_python/data/L_Tsq.png diff --git a/lecture_notes/advanced_python/data/L_Tsq_Line.png b/lecture_notes/advanced_python/data/L_Tsq_Line.png Binary files differnew file mode 100644 index 0000000..5535eff --- /dev/null +++ b/lecture_notes/advanced_python/data/L_Tsq_Line.png diff --git a/lecture_notes/advanced_python/data/L_Tsq_points.png b/lecture_notes/advanced_python/data/L_Tsq_points.png Binary files differnew file mode 100644 index 0000000..3b8f2a3 --- /dev/null +++ b/lecture_notes/advanced_python/data/L_Tsq_points.png diff --git a/lecture_notes/advanced_python/data/company_a_data.txt b/lecture_notes/advanced_python/data/company_a_data.txt new file mode 100644 index 0000000..06f4ca4 --- /dev/null +++ b/lecture_notes/advanced_python/data/company_a_data.txt @@ -0,0 +1,2 @@ +2.000000000000000000e+03 2.001000000000000000e+03 2.002000000000000000e+03 2.003000000000000000e+03 2.004000000000000000e+03 2.005000000000000000e+03 2.006000000000000000e+03 2.007000000000000000e+03 2.008000000000000000e+03 2.009000000000000000e+03 2.010000000000000000e+03 +2.300000000000000000e+01 5.500000000000000000e+01 3.200000000000000000e+01 6.500000000000000000e+01 8.800000000000000000e+01 5.000000000000000000e+00 1.400000000000000000e+01 6.700000000000000000e+01 2.300000000000000000e+01 2.300000000000000000e+01 1.200000000000000000e+01 diff --git a/lecture_notes/advanced_python/data/error_bar.png b/lecture_notes/advanced_python/data/error_bar.png Binary files differnew file mode 100644 index 0000000..cc1a454 --- /dev/null +++ b/lecture_notes/advanced_python/data/error_bar.png diff --git a/lecture_notes/advanced_python/data/least_sq_fit.png b/lecture_notes/advanced_python/data/least_sq_fit.png Binary files differnew file mode 100644 index 0000000..dba2afb --- /dev/null +++ b/lecture_notes/advanced_python/data/least_sq_fit.png diff --git a/lecture_notes/advanced_python/data/pendulum.txt b/lecture_notes/advanced_python/data/pendulum.txt new file mode 100644 index 0000000..01da9b8 --- /dev/null +++ b/lecture_notes/advanced_python/data/pendulum.txt @@ -0,0 +1,90 @@ +1.0000e-01 6.9004e-01 +1.1000e-01 6.9497e-01 +1.2000e-01 7.4252e-01 +1.3000e-01 7.5360e-01 +1.4000e-01 8.3568e-01 +1.5000e-01 8.6789e-01 +1.6000e-01 8.4182e-01 +1.7000e-01 8.5379e-01 +1.8000e-01 8.5762e-01 +1.9000e-01 8.8390e-01 +2.0000e-01 8.9985e-01 +2.1000e-01 9.8436e-01 +2.2000e-01 1.0244e+00 +2.3000e-01 1.0572e+00 +2.4000e-01 9.9077e-01 +2.5000e-01 1.0058e+00 +2.6000e-01 1.0727e+00 +2.7000e-01 1.0943e+00 +2.8000e-01 1.1432e+00 +2.9000e-01 1.1045e+00 +3.0000e-01 1.1867e+00 +3.1000e-01 1.1385e+00 +3.2000e-01 1.2245e+00 +3.3000e-01 1.2406e+00 +3.4000e-01 1.2071e+00 +3.5000e-01 1.2658e+00 +3.6000e-01 1.2995e+00 +3.7000e-01 1.3142e+00 +3.8000e-01 1.2663e+00 +3.9000e-01 1.2578e+00 +4.0000e-01 1.2991e+00 +4.1000e-01 1.3058e+00 +4.2000e-01 1.3478e+00 +4.3000e-01 1.3506e+00 +4.4000e-01 1.4044e+00 +4.5000e-01 1.3948e+00 +4.6000e-01 1.3800e+00 +4.7000e-01 1.4480e+00 +4.8000e-01 1.4168e+00 +4.9000e-01 1.4719e+00 +5.0000e-01 1.4656e+00 +5.1000e-01 1.4399e+00 +5.2000e-01 1.5174e+00 +5.3000e-01 1.4988e+00 +5.4000e-01 1.4751e+00 +5.5000e-01 1.5326e+00 +5.6000e-01 1.5297e+00 +5.7000e-01 1.5372e+00 +5.8000e-01 1.6094e+00 +5.9000e-01 1.6352e+00 +6.0000e-01 1.5843e+00 +6.1000e-01 1.6643e+00 +6.2000e-01 1.5987e+00 +6.3000e-01 1.6585e+00 +6.4000e-01 1.6317e+00 +6.5000e-01 1.7074e+00 +6.6000e-01 1.6654e+00 +6.7000e-01 1.6551e+00 +6.8000e-01 1.6964e+00 +6.9000e-01 1.7143e+00 +7.0000e-01 1.7706e+00 +7.1000e-01 1.7622e+00 +7.2000e-01 1.7260e+00 +7.3000e-01 1.8089e+00 +7.4000e-01 1.7905e+00 +7.5000e-01 1.7428e+00 +7.6000e-01 1.8381e+00 +7.7000e-01 1.8182e+00 +7.8000e-01 1.7865e+00 +7.9000e-01 1.7995e+00 +8.0000e-01 1.8296e+00 +8.1000e-01 1.8625e+00 +8.2000e-01 1.8623e+00 +8.3000e-01 1.8383e+00 +8.4000e-01 1.8593e+00 +8.5000e-01 1.8944e+00 +8.6000e-01 1.9598e+00 +8.7000e-01 1.9000e+00 +8.8000e-01 1.9244e+00 +8.9000e-01 1.9397e+00 +9.0000e-01 1.9440e+00 +9.1000e-01 1.9718e+00 +9.2000e-01 1.9383e+00 +9.3000e-01 1.9555e+00 +9.4000e-01 2.0006e+00 +9.5000e-01 1.9841e+00 +9.6000e-01 2.0066e+00 +9.7000e-01 2.0493e+00 +9.8000e-01 2.0503e+00 +9.9000e-01 2.0214e+00 diff --git a/lecture_notes/advanced_python/data/pendulum_error.txt b/lecture_notes/advanced_python/data/pendulum_error.txt new file mode 100644 index 0000000..5cf2194 --- /dev/null +++ b/lecture_notes/advanced_python/data/pendulum_error.txt @@ -0,0 +1,90 @@ +1.0000e-01 6.9004e-01 0.03 0.02 +1.1000e-01 6.9497e-01 0.05 0.03 +1.2000e-01 7.4252e-01 0.02 0.01 +1.3000e-01 7.5360e-01 0.02 0.04 +1.4000e-01 8.3568e-01 0.04 0.00 +1.5000e-01 8.6789e-01 0.01 0.03 +1.6000e-01 8.4182e-01 0.01 0.02 +1.7000e-01 8.5379e-01 0.04 0.02 +1.8000e-01 8.5762e-01 0.02 0.02 +1.9000e-01 8.8390e-01 0.03 0.02 +2.0000e-01 8.9985e-01 0.00 0.03 +2.1000e-01 9.8436e-01 0.04 0.00 +2.2000e-01 1.0244e+00 0.01 0.01 +2.3000e-01 1.0572e+00 0.05 0.04 +2.4000e-01 9.9077e-01 0.05 0.04 +2.5000e-01 1.0058e+00 0.01 0.02 +2.6000e-01 1.0727e+00 0.03 0.02 +2.7000e-01 1.0943e+00 0.03 0.03 +2.8000e-01 1.1432e+00 0.04 0.02 +2.9000e-01 1.1045e+00 0.01 0.02 +3.0000e-01 1.1867e+00 0.00 0.01 +3.1000e-01 1.1385e+00 0.04 0.00 +3.2000e-01 1.2245e+00 0.04 0.04 +3.3000e-01 1.2406e+00 0.00 0.03 +3.4000e-01 1.2071e+00 0.03 0.03 +3.5000e-01 1.2658e+00 0.05 0.03 +3.6000e-01 1.2995e+00 0.03 0.02 +3.7000e-01 1.3142e+00 0.05 0.03 +3.8000e-01 1.2663e+00 0.00 0.00 +3.9000e-01 1.2578e+00 0.03 0.03 +4.0000e-01 1.2991e+00 0.00 0.03 +4.1000e-01 1.3058e+00 0.03 0.04 +4.2000e-01 1.3478e+00 0.05 0.03 +4.3000e-01 1.3506e+00 0.01 0.01 +4.4000e-01 1.4044e+00 0.02 0.02 +4.5000e-01 1.3948e+00 0.03 0.01 +4.6000e-01 1.3800e+00 0.05 0.02 +4.7000e-01 1.4480e+00 0.03 0.03 +4.8000e-01 1.4168e+00 0.04 0.01 +4.9000e-01 1.4719e+00 0.02 0.04 +5.0000e-01 1.4656e+00 0.03 0.04 +5.1000e-01 1.4399e+00 0.01 0.01 +5.2000e-01 1.5174e+00 0.03 0.02 +5.3000e-01 1.4988e+00 0.00 0.00 +5.4000e-01 1.4751e+00 0.05 0.01 +5.5000e-01 1.5326e+00 0.05 0.02 +5.6000e-01 1.5297e+00 0.05 0.00 +5.7000e-01 1.5372e+00 0.00 0.02 +5.8000e-01 1.6094e+00 0.02 0.03 +5.9000e-01 1.6352e+00 0.02 0.03 +6.0000e-01 1.5843e+00 0.04 0.00 +6.1000e-01 1.6643e+00 0.05 0.01 +6.2000e-01 1.5987e+00 0.01 0.02 +6.3000e-01 1.6585e+00 0.01 0.03 +6.4000e-01 1.6317e+00 0.04 0.00 +6.5000e-01 1.7074e+00 0.03 0.00 +6.6000e-01 1.6654e+00 0.03 0.01 +6.7000e-01 1.6551e+00 0.04 0.03 +6.8000e-01 1.6964e+00 0.01 0.02 +6.9000e-01 1.7143e+00 0.01 0.02 +7.0000e-01 1.7706e+00 0.01 0.03 +7.1000e-01 1.7622e+00 0.02 0.03 +7.2000e-01 1.7260e+00 0.04 0.03 +7.3000e-01 1.8089e+00 0.05 0.01 +7.4000e-01 1.7905e+00 0.04 0.03 +7.5000e-01 1.7428e+00 0.01 0.01 +7.6000e-01 1.8381e+00 0.01 0.03 +7.7000e-01 1.8182e+00 0.00 0.03 +7.8000e-01 1.7865e+00 0.04 0.02 +7.9000e-01 1.7995e+00 0.04 0.02 +8.0000e-01 1.8296e+00 0.04 0.02 +8.1000e-01 1.8625e+00 0.02 0.04 +8.2000e-01 1.8623e+00 0.02 0.03 +8.3000e-01 1.8383e+00 0.04 0.02 +8.4000e-01 1.8593e+00 0.04 0.00 +8.5000e-01 1.8944e+00 0.03 0.02 +8.6000e-01 1.9598e+00 0.00 0.03 +8.7000e-01 1.9000e+00 0.04 0.01 +8.8000e-01 1.9244e+00 0.01 0.00 +8.9000e-01 1.9397e+00 0.03 0.02 +9.0000e-01 1.9440e+00 0.03 0.02 +9.1000e-01 1.9718e+00 0.05 0.02 +9.2000e-01 1.9383e+00 0.02 0.02 +9.3000e-01 1.9555e+00 0.05 0.04 +9.4000e-01 2.0006e+00 0.00 0.02 +9.5000e-01 1.9841e+00 0.00 0.02 +9.6000e-01 2.0066e+00 0.02 0.01 +9.7000e-01 2.0493e+00 0.05 0.03 +9.8000e-01 2.0503e+00 0.03 0.03 +9.9000e-01 2.0214e+00 0.03 0.04 diff --git a/lecture_notes/advanced_python/exercises.rst b/lecture_notes/advanced_python/exercises.rst new file mode 100644 index 0000000..eeaa323 --- /dev/null +++ b/lecture_notes/advanced_python/exercises.rst @@ -0,0 +1,56 @@ +Exercises +========= + +#. Consider the iteration :math:`$x_{n+1} = f(x_n)$` where + :math:`$f(x) = kx(1-x)$`. Plot the successive iterates of this + process. + +#. Plot this using a cobweb plot as follows: + + #. Start at :math:`$(x_0, 0)$` + #. Draw line to :math:`$(x_i, f(x_i))$`; + #. Set :math:`$x_{i+1} = f(x_i)$` + #. Draw line to :math:`$(x_i, x_i)$` + #. Repeat from 2 for as long as you want + +#. Plot the Koch snowflake. Write a function to generate the necessary + points given the two points constituting a line. + + #. Split the line into 4 segments. + #. The first and last segments are trivial. + #. To rotate the point you can use complex numbers, recall that + :math:`$z e^{j \theta}$` rotates a point :math:`$z$` in 2D by + :math:`$\theta$`. + #. Do this for all line segments till everything is done. + +#. Show rate of convergence for a first and second order finite + difference of sin(x) + +#. Given, the position of a projectile in in ``pos.txt``, plot it's + trajectory. + + - Label both the axes. + - What kind of motion is this? + - Title the graph accordingly. + - Annotate the position where vertical velocity is zero. + +#. Write a Program that plots a regular n-gon(Let n = 5). + +#. Create a sequence of images in which the damped oscillator + (:math:`$e^{-x/10}sin(x)$`) slowly evolves over time. + +#. Given a list of numbers, find all the indices at which 1 is present. + numbers = [1, 1, 3, 4, 3, 6, 7, 8, 1, 2, 4, 1] + +#. Given a list of numbers, find all the indices at which 1 is present. + numbers = [1, 1, 3, 4, 3, 6, 7, 8, 1, 2, 4, 1]. Solve the problem using a + functional approach. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + diff --git a/lecture_notes/advanced_python/handout.rst b/lecture_notes/advanced_python/handout.rst new file mode 100644 index 0000000..2cd3618 --- /dev/null +++ b/lecture_notes/advanced_python/handout.rst @@ -0,0 +1,14 @@ +================= + Advanced Python +================= + +.. include :: plotting.rst +.. include :: arrays.rst +.. include :: scipy.rst +.. include :: modules.rst +.. include :: oop.rst +.. include :: lambda.rst +.. include :: sage.rst +.. include :: rst.rst + + diff --git a/lecture_notes/advanced_python/images/L-Tsq.png b/lecture_notes/advanced_python/images/L-Tsq.png Binary files differnew file mode 100644 index 0000000..cc1a454 --- /dev/null +++ b/lecture_notes/advanced_python/images/L-Tsq.png diff --git a/lecture_notes/advanced_python/images/bar.png b/lecture_notes/advanced_python/images/bar.png Binary files differnew file mode 100644 index 0000000..cee54fb --- /dev/null +++ b/lecture_notes/advanced_python/images/bar.png diff --git a/lecture_notes/advanced_python/images/cosine.png b/lecture_notes/advanced_python/images/cosine.png Binary files differnew file mode 100644 index 0000000..2b15a32 --- /dev/null +++ b/lecture_notes/advanced_python/images/cosine.png diff --git a/lecture_notes/advanced_python/images/epid.png b/lecture_notes/advanced_python/images/epid.png Binary files differnew file mode 100644 index 0000000..e1c7e08 --- /dev/null +++ b/lecture_notes/advanced_python/images/epid.png diff --git a/lecture_notes/advanced_python/images/fsolve.png b/lecture_notes/advanced_python/images/fsolve.png Binary files differnew file mode 100644 index 0000000..0108215 --- /dev/null +++ b/lecture_notes/advanced_python/images/fsolve.png diff --git a/lecture_notes/advanced_python/images/loglog.png b/lecture_notes/advanced_python/images/loglog.png Binary files differnew file mode 100644 index 0000000..824b9f1 --- /dev/null +++ b/lecture_notes/advanced_python/images/loglog.png diff --git a/lecture_notes/advanced_python/images/lst-sq-fit.png b/lecture_notes/advanced_python/images/lst-sq-fit.png Binary files differnew file mode 100644 index 0000000..7e9dfe2 --- /dev/null +++ b/lecture_notes/advanced_python/images/lst-sq-fit.png diff --git a/lecture_notes/advanced_python/images/ode.png b/lecture_notes/advanced_python/images/ode.png Binary files differnew file mode 100644 index 0000000..c76a483 --- /dev/null +++ b/lecture_notes/advanced_python/images/ode.png diff --git a/lecture_notes/advanced_python/images/overlaid.png b/lecture_notes/advanced_python/images/overlaid.png Binary files differnew file mode 100644 index 0000000..41e1891 --- /dev/null +++ b/lecture_notes/advanced_python/images/overlaid.png diff --git a/lecture_notes/advanced_python/images/pie.png b/lecture_notes/advanced_python/images/pie.png Binary files differnew file mode 100644 index 0000000..7791e54 --- /dev/null +++ b/lecture_notes/advanced_python/images/pie.png diff --git a/lecture_notes/advanced_python/images/plot.png b/lecture_notes/advanced_python/images/plot.png Binary files differnew file mode 100644 index 0000000..89cbc46 --- /dev/null +++ b/lecture_notes/advanced_python/images/plot.png diff --git a/lecture_notes/advanced_python/images/roots.png b/lecture_notes/advanced_python/images/roots.png Binary files differnew file mode 100644 index 0000000..c13a1a4 --- /dev/null +++ b/lecture_notes/advanced_python/images/roots.png diff --git a/lecture_notes/advanced_python/images/scatter.png b/lecture_notes/advanced_python/images/scatter.png Binary files differnew file mode 100644 index 0000000..66bd5d8 --- /dev/null +++ b/lecture_notes/advanced_python/images/scatter.png diff --git a/lecture_notes/advanced_python/images/sine.png b/lecture_notes/advanced_python/images/sine.png Binary files differnew file mode 100644 index 0000000..7667886 --- /dev/null +++ b/lecture_notes/advanced_python/images/sine.png diff --git a/lecture_notes/advanced_python/images/slice.png b/lecture_notes/advanced_python/images/slice.png Binary files differnew file mode 100644 index 0000000..7f53d2a --- /dev/null +++ b/lecture_notes/advanced_python/images/slice.png diff --git a/lecture_notes/advanced_python/images/squares.png b/lecture_notes/advanced_python/images/squares.png Binary files differnew file mode 100644 index 0000000..ee102e6 --- /dev/null +++ b/lecture_notes/advanced_python/images/squares.png diff --git a/lecture_notes/advanced_python/images/subplot.png b/lecture_notes/advanced_python/images/subplot.png Binary files differnew file mode 100644 index 0000000..2c1a662 --- /dev/null +++ b/lecture_notes/advanced_python/images/subplot.png diff --git a/lecture_notes/advanced_python/lambda.rst b/lecture_notes/advanced_python/lambda.rst new file mode 100644 index 0000000..4660300 --- /dev/null +++ b/lecture_notes/advanced_python/lambda.rst @@ -0,0 +1,225 @@ +Functional programming +====================== + +In this section, we shall look at a different style of programming called +Functional programming, which is supported by Python. + +The fundamental idea behind functional programming is that the output of a +function, should not depend on the state of the program. It should only +depend on the inputs to the program and should return the same output, +whenever the function is called with the same arguments. Essentially, the +functions of our code, behave like mathematical functions, where the output +is dependent only on the variables on which the function depends. There is +no "state" associated with the program. + +Let's look at some of the functionality that Python provides for writing +code in the Functional approach. + +List Comprehensions +------------------- + +Let's take a very simple problem to illustrate how list comprehensions +work. Let's say, we are given a list of weights of people, and we need to +calculate the corresponding weights on the moon. Essentially, return a new +list, with each of the values divided by 6.0. + +It's a simple problem, and let's first solve it using a ``for`` loop. We +shall initialize a new empty, list and keep appending the new weights +calculated + +:: + + weights = [30, 45.5, 78, 81, 55.5, 62.5] + + weights_moon = [] + + for w in weights: + weights_moon.append(w/6.0) + + print weights_moon + +We had to initialize an empty list, and write a ``for`` loop that appends +each of the values to the new list. List comprehensions provide a way of +writing a one liner, that does the same thing, without resorting to +initializing a new empty list. Here's how we would do it, using list +comprehensions + +:: + + [ w/6.0 for w in weights ] + +As we can see, we have the same list, that we obtained previously, using +the ``for`` loop. + +Let's now look at a slightly more complex example, where we wish to +calculate the weights on the moon, only if the weight on the earth is +greater than 50. + +:: + + weights = [30, 45.5, 78, 81, 55.5, 62.5] + weights_moon = [] + for w in weights: + if w > 50: + weights_moon.append(w/6.0) + + print weights_moon + +The ``for`` loop above can be translated to a list comprehension as shown + +:: + + [ w/6.0 for w in weights if w>50 ] + +Now, let's change the problem again. Say, we wish to give the weight on the +moon (divide by 6), when the weight is greater than 50, otherwise triple +the weight. + +:: + + weights = [30, 45.5, 78, 81, 55.5, 62.5] + weights_migrate = [] + for w in weights: + if w > 50: + weights_migrate.append(w/6.0) + else: + weights_migrate.append(w * 3.0) + + print weights_migrate + +This problem, however, cannot be translated into a list comprehension. We +shall use the ``map`` built-in, to solve the problem in a functional +style. + +``map`` +------- + +But before getting to the more complex problem, let's solve the easier +problem of returning the weight on moon for all the weights. + +The ``map`` function essentially allows us to apply a function to all the +elements of a list, and returns a new list that consists of the outputs +from each of the call. So, to use ``map`` we need to define a function, +that takes an input and returns a sixth of it. + +:: + + def moonize(weight): + return weight/6.0 + +Now, that we have our ``moonize`` function, we can pass the function and the +list of weights as an argument to ``map`` and get the required list. + +:: + + map(moonize, weights) + +Let's define a new function, that compares the weight value with 50 and +returns a new value based on the condition. + +:: + + def migrate(weight): + if weight < 50: + return weight*3.0 + else: + return weight/6.0 + +Now, we can use ``map`` to obtain the new weight values + +:: + + map(migrate, weights) + +As you can see, we obtained the result, that we obtained before. + +But, defining such functions each time, is slightly inconvenient. We are +not going to use these functions at any later point, in our code. So, it is +slightly wasteful to define functions for this. Wouldn't it be nice to +write them, without actually defining functions? Enter ``lambda``! + +``lambda`` +---------- + +Essentially, lambda allows us to define small functions anonymously. The +first example that uses the ``moonize`` function can now be re-written as +below, using the lambda function. + +:: + + map(lambda x: x/6.0, weights) + +``lambda`` above is defining a function, which takes one argument ``x`` and +returns a sixth of that argument. The ``lambda`` actually returns a +function object which we could in fact assign to a name and use later. + +:: + + l_moonize = lambda x: x/6.0 + +The ``l_moonize`` function, now behaves similarly to the ``moonize`` +function. + +The ``migrate`` function can be written using a lambda function as below + +:: + + l_migrate = lambda x: x*3.0 if x < 50 else x/6.0 + + +If you observed, we have carefully avoided the discussion of the example +where only the weights that were above 50 were calculated and returned. +This is because, this cannot be done using ``map``. We may return ``None`` +instead of calculating a sixth of the element, but we cannot ensure that +the element is not present in the new list. + +This can be done using ``filter`` and ``map`` in conjunction. + +``filter`` +---------- + +The ``filter`` function, like the ``map`` takes two arguments, a function +and a sequence and calls the function for each element of the sequence. The +output of ``filter`` is a sequence consisting of elements for which the +function returned ``True`` + +The problem of returning a sixth of only those weights which are more than +50, can be solved as below + +:: + + map(lambda x: x/6.0, filter(lambda x: x > 50, weights)) + +The ``filter`` function returns a list containing only the values which are +greater than 50. + +:: + + filter(lambda x: x > 50, weights) + + +``reduce`` +---------- + +As, the name suggests, ``reduce`` reduces a sequence to a single object. +``reduce`` takes two arguments, a function and a sequence, but the function +should take two arguments as input. + +``reduce`` initially passes the first two elements as arguments, and +continues iterating of the sequence and passes the output of the previous +call with the current element, as the arguments to the function. The final +result therefore, is just a single element. + +:: + + reduce(lambda x,y: x*y, [1, 2, 3, 4]) + +multiplies all the elements of the list and returns ``24``. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/module_plan.rst b/lecture_notes/advanced_python/module_plan.rst new file mode 100644 index 0000000..2ee4925 --- /dev/null +++ b/lecture_notes/advanced_python/module_plan.rst @@ -0,0 +1,79 @@ +Advanced Python +=============== + +Module Objectives +----------------- + +After successfully completing this module a participant will be able to: + +* generate 2D plots {Ap} +* Work with arrays and use them effectively {Ap} +* Solve linear, polynomial and other non-linear equations {Ap} +* Solve ODEs {Ap} +* Write mid-sized programs that carry out typical {Ap} + engineering/numerical computations such as those that involve + (basic) manipulation of large arrays in an efficient manner + ++---------+-----------------------------------+----------+ +| Session | Topic | Duration | ++---------+-----------------------------------+----------+ +| | Interactive Plottin | 5 min | +| | - -pylab | | +| | - plot, linspace | | +| | | | +| | Embellishing plots | 10 min | +| | - clf | | +| | - title | | +| | - xlabel, ylabel | | +| | - annotate | | +| | - xlim, ylim | | +| | | | +| | Saving to scripts | 10 min | +| | - %hist | | +| | - %save | | +| | - %run | | +| | | | +| | Saving plots | | +| | | | +| | Multiple plots | 15 min | +| | - legend | | +| | - *figure* | | +| | - subplot | | +| | | | +| | Plotting data | 10 min | +| | - loadtxt | | +| | | | +| | Other plots | 10 min | +| | - bar, | | +| | - pie | | +| | - scatter | | +| | - loglog | | ++---------+-----------------------------------+----------+ +| | Arrays - Introduction | 15 min | +| | - creating from lists | | +| | - special methods | | +| | - operations on arrays | | +| | | | +| | Accessing pieces of arrays | 15 min | +| | - accessing and changing elements | | +| | - rows and columns | | +| | - slicing and striding | | +| | | | +| | Matrix operations | 10 min | +| | | | +| | Least square fit | 15 min | ++---------+-----------------------------------+----------+ +| | Solving equations | 15 min | +| | - solve | | +| | - roots | | +| | - fsolve | | +| | | | +| | ODEs | 20 min | +| | - 1st order | | +| | - 2nd order | | +| | | | +| | python modules | 20 min | +| | - imports | | +| | - sys.path | | +| | - writing own modules | | ++---------+-----------------------------------+----------+ diff --git a/lecture_notes/advanced_python/modules.rst b/lecture_notes/advanced_python/modules.rst new file mode 100644 index 0000000..f3df676 --- /dev/null +++ b/lecture_notes/advanced_python/modules.rst @@ -0,0 +1,278 @@ +Using Python modules +==================== + +We shall, in this section, see how to run Python scripts from the command +line, and more details about importing modules. + +Let us create a simple python script to print hello world. Open your text +editor and type the following, and save the script as ``hello.py``. + +:: + + print "Hello world!" + +Until now we have been running scripts from inside IPython, using + +:: + + %run -i hello.py + +But, as we know, IPython is just an advanced interpreter and it is not +mandatory that every one who wants to run your program has IPython +installed. + +So, the right method to run the script, would be to run it using the Python +interpreter. Open the terminal and navigate to the directory where +``hello.py`` is saved. + +Then run the script by saying, +:: + + python hello.py + +The script is executed and the string ``Hello World!`` has been printed. + +Now let us run a script that plots a simple sine curve in the range -2pi to +2pi, using Python, instead of running it from within IPython. + +Type the following lines and save it in ``sine_plot.py`` file. + +:: + + x = linspace(-2*pi, 2*pi, 100) + plot(x, sin(x)) + show() + +Now let us run sine_plot.py as a python script. + +:: + + python sine_plot.py + +Do we get the plot? No! All we get is error messages. Python complains that +``linspace`` isn't defined. What happened? Let us try to run the same +script from within IPython. Start IPython, with the ``-pylab`` argument and +run the script. It works! + +What is going on, here? IPython when started with the ``-pylab`` option, is +importing a whole set of functionality for us to work with, without +bothering about importing etc. + +Let us now try to fix the problem by importing ``linspace``. + +Let's add the following line as the first line in the script. + +:: + + from scipy import * + +Now let us run the script again, + +:: + + python sine_plot.py + +Now we get an error, that says ``plot`` is not defined. Let's edit the file +and import this from pylab. Let's add the following line, as the second +line of our script. + +:: + + from pylab import * + +And run the script, + +:: + + python sine_plot.py + +Yes! it worked. So what did we do? + +We actually imported the required functions and keywords, using ``import``. +By using the * , we are asking python to import everything from the +``scipy`` and ``pylab`` modules. This isn't a good practice, as +1. it imports a lot of unnecessary things +2. the two modules may have functions with the same name, which would + cause a conflict. + +One of the ways out is to import only the stuff that we need, explicitly. + +Let us modify sine_plot.py by replacing the import statements with the +following lines. + +:: + + from scipy import linspace, pi, sin + from pylab import plot, show + +Now let us try running the code again as, + +:: + + python show_plot.py + +As expected, this works. But, once the number of functions that you need to +import increases, this is slightly inconvenient. Also, you cannot use +functions with the same name, from different modules. To overcome this, +there's another method. + +We could just import the modules as it is, and use the functions or other +objects as a part of those modules. Change the import lines, to the +following. + +:: + + import scipy + import pylab + +Now, replace ``pi`` with ``scipy.pi``. Similarly, for ``sin`` and +``linspace``. Replace ``plot`` and ``show`` with ``pylab.plot`` and +``pylab.show``, respectively. + +Now, run the file and see that we get the output, as expected. + +We have learned how to import from modules, but what exactly is a module? +How is one written? + +A module is simply a Python script containing the definitions and +statements, which can be imported. So, it is very easy to create your own +modules. You just need to stick in all your definitions into your python +file and put the file in your current directory. + +When importing, Python searches the locations present in a variable called +the Python path. So, our module file should be present in one of the +locations in the Python path. The first location to be searched is the +current directory of the script being run. So, having our module file in +the current working directory, is the simplest way to allow it to be used +as a module and import things from it. + +Python has a very rich standard library of modules. It is very extensive, +offering a wide range of facilities. Some of the standard modules are, + +for Math: math, random +for Internet access: urllib2, smtplib +for System, Command line arguments: sys +for Operating system interface: os +for regular expressions: re +for compression: gzip, zipfile, tarfile +And there are lot more. + +Find more information at Python Library reference, +``http://docs.python.org/library/`` + +There are a lot of other modules like pylab, scipy, Mayavi, etc which +are not part of the standard Python library. + +This brings us to the end of our discussion on modules and running scripts +from the command line. + +Writing modules +=============== + +In this section we shall look at writing modules, in some more detail. +Often we will have to reuse the code that we have previously written. We do +that by writing functions. Functions can then be put into modules, and +imported as and when required. + +Let us first write a function that computes the gcd of two numbers and save it in a script. + +:: + + def gcd(a, b): + while b: + a, b = b, a%b + return a + +Now, we shall write a test function in the script that tests the gcd function, to see if it works. + +:: + + if gcd(40, 12) == 4 and gcd(12, 13) == 1: + print "Everything OK" + else: + print "The GCD function is wrong" + +Let us save the file as gcd_script.py in ``/home/fossee/gcd_script.py`` and +run it. + +:: + + $ python /home/fossee/gcd_script.py + +We can see that the script is executed and everything is fine. + +What if we want to use the gcd function in some of our other scripts. This +is also possible since every python file can be used as a module. + +But first, we shall understand what happens when you import a module. + +Open IPython and type + +:: + + import sys + sys.path + +This is a list of locations where python searches for a module when it +encounters an import statement. Hence, when we just did ``import sys``, +python searches for a file named ``sys.py`` or a folder named ``sys`` in +all these locations one by one, until it finds one. We can place our script +in any one of these locations and import it. + +The first item in the list is an empty string which means the current +working directory is also searched. + +Alternatively, we can also import the module if we are working in same +directory where the script exists. + +Since we are in /home/fossee, we can simply do + +:: + + import gcd_script + +We can see that the gcd_script is imported. But the test code that we added +at the end of the file is also executed. + +But we want the test code to be executed only when the file is run as a +python script and not when it is imported. + +This is possible by using ``__name__`` variable. + + +Go to the file and add + +:: + + if __name__ == "__main__": + +before the test code and indent the test code. + +Let us first run the code. + +:: + + $ python gcd_script.py + +We can see that the test runs successfully. + +Now we shall import the file + +:: + + import gcd_script + +We see that now the test code is not executed. + +The ``__name__`` variable is local to every module and it is equal to +``__main__`` only when the file is run as a script. Hence, all the code +that goes in to the if block, ``if __name__ == "__main__":`` is executed +only when the file is run as a python script. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/more_arrays.rst b/lecture_notes/advanced_python/more_arrays.rst new file mode 100644 index 0000000..c562edd --- /dev/null +++ b/lecture_notes/advanced_python/more_arrays.rst @@ -0,0 +1,310 @@ +More Arrays +=========== + +In this section, we shall explore arrays a bit more, since they are the +fundamental building block of all the computation work we wish to do. + +Arrays were introduced, stating that they are very fast as compared to +lists, owing to their homogeneity. They are definitely a lot more +convenient than a list of lists for doing element-wise operations. Let's +now look at the speed difference, quantitatively. + +Arrays vs. Lists +---------------- + +Let us create a large array with, say a million elements and see how long +it takes to get a new sequence that contains the ``sin`` of each of these +elements. + +:: + + a = linspace(0, 2*pi, 1000000) + + sin(a) + + b = [] + for i in a: b.append(sin(i)) + +There is a visible difference in the run-time of the two ways of doing it. +But, let's look at it quantitatively using the ``%timeit`` magic command of +IPython to get a quantitative difference between doing is using a ``for`` +loop and using the array way of doing it. + +:: + + %timeit sin(a) + + b = [] + %timeit for i in a: b.append(sin(i)) + +The first method turns out to be around 70 times faster on my machine. So, +as you can see, the homogeneity. The speed gains due to homogeneity are +because, the loops are run in C, rather than in Python and Python loops are +comparatively much slower than C loops. + +Fancy Indexing +-------------- + +We have looked at slicing and striding to get pieces of arrays. But they +only allow us to do so much. + +For instance, let's say, we have an array a of length 40 with some random +elements. We wish to get a new array which is obtained by dropping every +element that is at a position that is a multiple of 8, i.e., we wish to +drop the elements 0, 8, 16, 24, 32. How do we go about doing this? +Essentially, we wish to drop the elements a[::8]. We shall use something +called Boolean arrays to solve this problem. + +Let's look at a small example before solving this problem. + +:: + + p = array([1, 2, 3]) + q = array([True, False, True]) + + p[q] + +``q`` is called a Boolean array and can be used to index another array. +Only the elements at positions corresponding to ``True`` values in q, will +be returned. + +Now, to solve the problem of dropping the elements a[::8] from a, we need +to create a Boolean array, with those elements as ``False`` and the rest as +``True``. There could be multiple ways of doing that. Here's one + +:: + + b = arange(len(a)) + b%8!=0 + + a[b%8!=0] + +Checking if the elements of ``b`` are not multiples of 8, returns a Boolean +array, which we are then using to index ``a``. + +Numpy arrays can also be indexed using arrays of indices. Let's solve the +same problem using arrays with indices. Let's look at the same small +example that we looked at, for Boolean arrays, before solving the actual +problem. + +:: + + p = array([1, 2, 3]) + q = array([0, 2]) + + p[q] + +The array ``q`` has the indices of the elements that we wish to pick out of +the array ``p``. The order in which the indices are present, doesn't +matter. The returned array, will contain the elements of ``p`` in the order +in which they have been indexed. They can even be repeated, if we wish to +get the same element out of ``p``. + +:: + + r = array([2, 0]) + p[r] + + s = array([1, 1]) + p[s] + +Now, to solve the problem of dropping all the elements of ``p`` whose +indices are a multiple of 8, we need to generate an array, which doesn't +have these elements. + +:: + + q = array([i for i in range(40) if i%8]) + p[q] + +Copies and Views +---------------- + +Simple assignment of mutable objects, do not make copies in Python. For +instance, + +:: + + a = array([1, 2, 3]) + b = a + +Here, ``b`` and ``a`` are not copies of each other, but different names for +the same object. If one of them is changed, it reflects in the other one, +as well. By the way, if you recall, this behaviour is similar with lists as +well. + +:: + + a[0] = 1 + print a, b + + +Slicing an array, returns a view of it. Assigning the slice of an object to +a new variable, means the new variable references a portion of the data of +the original object. Hence, changing the data of the new variable, changes +the original variable, as well. + +:: + + a = arange(10) + b = a[5:] + + b[:] = 5 + print b, a + +If we require a complete (or deep) copy of the data of an array, we should +use the ``copy()`` method. + +:: + + a = arange(10) + b = a[5:].copy() + + b[:] = 5 + print b, a + +Broadcasting +------------ + +Let's now look at a more advanced concept called Broadcasting. The +broadcasting rules help us understand how Numpy deals with arrays of +different dimensions. + +We know that array operations are element-wise, and for them to work, the +two arrays should be of the same shape. + +For instance, + +:: + + a = array([1, 2, 3, 4]) + b = array([2, 4, 6, 8]) + + a * b + +works, but, + +:: + + a = array([1, 2, 3, 4]) + c = array([6, 8, 10]) + + a * c + +does not work, which is expected. But, surprisingly (or may be not so +surprisingly, since we have seen it before) multiplication of a vector with +a scalar works. + +:: + + a = array([1, 2, 3, 4]) + c = 6 + + a * c + +The above multiplication works, thanks to Broadcasting. Let us look at +another example of Broadcasting before looking at the general rules of +broadcasting. + +:: + + x = array([1, 2, 3]) + y = array([4, 5, 6]) + x+y + + y.shape = 3, 1 + print x, y + x+y + +When we are operating on two arrays, Numpy broadcasts the arrays, so that +the shape of the two arrays becomes the same. Then the required operation +is performed on the two arrays. + +The procedure of broadcasting is as follows. + +1. When operating on two arrays, the arrays with the smaller number of + dimensions, has 1s prepended to it's shape, so that the number of + dimensions of both the arrays becomes the same. +2. The size in each dimension of the output shape is the maximum of all the + input shapes in that dimension. +3. An input can be used in the calculation if its shape in a particular + dimension either matches the output shape or has value exactly 1. +4. If an input has a dimension size of 1 in its shape, the first data entry + in that dimension will be used for all + +Let's look at the example of adding ``x`` and ``y`` to each other, step by +step. + +:: + + x.shape + y.shape + +``x.shape`` is (3,) and ``y.shape`` is (3,1). Now, ``x`` has the smaller +dimensions of the two. 1 is prepended to the shape of x, until both the +arrays have the same dimension. ``x.shape`` becomes (1, 3). + +Now, by rule 2, we know that the output shape is the maximum of all the +input shapes, in each of the dimensions. So, the shape of the output is +expect to be (3, 3) + +The condition 3 satisfies, for both ``x`` and ``y``. So, this is a valid +operation on ``x`` and ``y``. + +To see how the last step works, we use the ``broadcast_arrays`` command. + +:: + + broadcast_arrays(x, y) + +The values of ``x`` are broadcasted or copied, in the dimension where it's +size was 1. Similarly, for ``y``. + +Let's look at another example, before ending our discussion on +Broadcasting. Let's say we have the co-ordinates of a set of points, and we +wish to calculate the distance of a new point from each of these points. + +:: + + x = array([[ 2., 2.], + [ 6., 9.], + [ 6., 6.], + [ 9., 0.]]) + + y = array([4., 3.]) + +We shall use broadcasting to calculate the difference between ``y`` and each of +the points in ``x``. + +:: + + x - y + +The array ``y`` has been broadcast and the difference has been obtained. +The following commands, will now give us the required distances. + +:: + + (x-y)**2 + sqrt(sum((x-y)**2, axis=1)) + +As you can see, broadcasting makes the code much simpler. Also, the +operation of subtracting ``y`` from each of the elements of ``x`` is +performed using iterations in the underlying C language, rather than us +writing ``for`` loops in Python. This turns out to be much faster, as long +as the array sizes are small. + +But this may turn out to be slower, when the number of objects gets larger. +This discussion is not in the scope of this course. Look at +`EricsBroadcastingDoc <http://www.scipy.org/EricsBroadcastingDoc>`_ for more +detail. + + + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/oop.rst b/lecture_notes/advanced_python/oop.rst new file mode 100644 index 0000000..b1ecbe8 --- /dev/null +++ b/lecture_notes/advanced_python/oop.rst @@ -0,0 +1,230 @@ +Object Oriented Programming +=========================== + +At the end of this section, you will be able to - + +- Understand the differences between Object Oriented Programming and + Procedural Programming +- Appreciate the need for Object Oriented Programming +- Read and understand Object Oriented Programs +- Write simple Object Oriented Programs + +Suppose we have a list of talks, to be presented at a conference. How would +we store the details of the talks? We could possibly have a dictionary for +each talk, that contains keys and values for Speaker, Title and Tags of the +talk. Also, say we would like to get the first name of the speaker and the +tags of the talk as a list, when required. We could do it, as below. + +:: + + talk = {'Speaker': 'Guido van Rossum', + 'Title': 'The History of Python' + 'Tags': 'python,history,C,advanced'} + + def get_first_name(talk): + return talk['Speaker'].split()[0] + + def get_tags(talk): + return talk['Tags'].split(',') + +This is fine, when we have a small number of talks and a small number of +operations that we wish to perform. But, as the number of talks increases, +this gets inconvenient. Say, you are writing another function in some other +module, that uses this ``talk`` dictionary, you will also need to pass the +functions that act on ``talk`` to that function. This gets quite messy, +when you have a lot of functions and objects. + +This is where Objects come in handy. Objects, essentially, group data with +the methods that act on the data into a single block/object. + +Objects and Methods +------------------- + +The idea of objects and object oriented programming is being introduced, +now, but this doesn't mean that we haven't come across objects. Everything +in Python is an object. We have been dealing with objects all the while. +Strings, lists, functions and even modules are objects in Python. As we +have seen, objects combine data along with functions that act upon the +data and we have been seeing this since the beginning. The functions that +are tied to an object are called methods. We have seen various methods, +until now. + +:: + + s = "Hello World" + s.lower() + + l = [1, 2, 3, 4, 5] + l.append(6) + +``lower`` is a string method and is being called upon ``s``, which is a +string object. Similarly, ``append`` is a list method, which is being +called on the list object ``l``. + +Functions are also objects and they can be passed to and returned from +functions, as we have seen in the SciPy section. + +Objects are also useful, because the provide a similar interface, without +us needing to bother about which exact type of object we are dealing with. +For example, we can iterate over the items in a sequence, as shown below +without really worrying about whether it's a list or a dictionary or a +file-object. + +:: + + for element in (1, 2, 3): + print element + for key in {'one':1, 'two':2}: + print key + for char in "123": + print char + for line in open("myfile.txt"): + print line + for line in urllib2.urlopen('http://site.com'): + print line + +All objects providing a similar inteface can be used the same way. + +Classes +------- + +When we created a string ``s``, we obtained an object of ``type`` string. + +:: + + s = "Hello World" + type(s) + +``s`` already comes with all the methods of strings. So, it suggests that +there should be some template, based on which the object ``s`` is built. +This template or blueprint to build an object is the Class. The class +definition gives the blueprint for building objects of that kind, and each +``object`` is an *instance* of that ``class``. + +As you would've expected, we can define our own classes in Python. Let us +define a simple Talk class for the example that we started this section +with. + +:: + + class Talk: + """A class for the Talks.""" + + def __init__(self, speaker, title, tags): + self.speaker = speaker + self.title = title + self.tags = tags + + def get_speaker_firstname(self): + return self.speaker.split()[0] + + def get_tags(self): + return self.tags.split(',') + +The above example introduces a lot of new things. Let us look at it, piece +by piece. + +A class is defined using a ``class`` block -- the keyword ``class`` +followed by the class name, in turn followed by a semicolon. All the +statements within the ``class`` are enclosed in it's block. Here, we have +defined a class named ``Talk``. + +Our class has the same two functions that we had defined before, to get the +speaker firstname and the tags. But along with that, we have a new function +``__init__``. We will see, what it is, in a short while. By the way, the +functions inside a class are called methods, as you already know. By +design, each method of a class requires to have the same instance of the +class, (i.e., the object) from which it was called as the first argument. +This argument is generally defined using ``self``. + +``self.speaker``, ``self.title`` and ``self.tags`` are variables that +contain the respective data. So, as you can see, we have combined the data +and the methods operating on it, into a single entity, an object. + +Let's now initialize a ``Talk`` which is equivalent to the example of the +talk, that we started with. Initializing an object is similar to calling a +function. + +:: + + bdfl = Talk('Guido van Rossum', + 'The History of Python', + 'python,history,C,advanced') + +We pass the arguments of the ``__init__`` function to the class name. We +are creating an object ``bdfl``, that is an instance of the class ``Talk`` +and represents the talk by Guido van Rossum on the History of Python. We +can now use the methods of the class, using the dot notation, that we have +been doing all the while. + +:: + + bdfl.get_tags() + bdfl.get_speaker_firstname() + +The ``__init__`` method is a special method, that is called, each time an +object is created from a class, i.e., an instance of a class is created. + +:: + + print bdfl.speaker + print bdfl.tags + print bdfl.title + +As you can see, the ``__init__`` method was called and the variables of the +``bdfl`` object have been set. object have been set. Also notice that, the +``__init__`` function takes 4 arguments, but we have passed only three. The +first argument ``self`` as we have already seen, is a reference to the +object itself. + + +Inheritance +----------- + +Now assume that we have a different category for Tutorials. They are almost +like talks, except that they can be hands-on or not. Now, we do not wish to +re-write the whole code that we wrote for the ``Talk`` class. Here, the +idea of inheritance comes in handy. We "inherit" the ``Talk`` class and +modify it to suit our needs. + +:: + + class Tutorial(Talk): + """A class for the tutorials.""" + + def __init__(self, speaker, title, tags, handson=True): + Talk.__init__(self, speaker, title, tags) + self.handson = handson + + def is_handson(self): + return self.handson + +We have now derived the ``Tutorial`` class from the ``Talk`` class. The +``Tutorial`` class, has a different ``__init__`` method, and a new +``is_handson`` method. But, since it is derived from the ``Talk`` method it +also has the methods, ``get_tags`` and ``get_speaker_firstname``. This +concept of inheriting methods and values is called inheritance. + +:: + + numpy = Tutorial('Travis Oliphant', 'Numpy Basics', 'numpy,python,beginner') + numpy.is_handson() + numpy.get_speaker_firstname() + +As you can see, it has saved a lot of code duplication and effort. + +That brings us to the end of the section on Object Oriented Programming. In +this section we have learnt, + +- the fundamental difference in paradigm, between Object Oriented + Programming and Procedural Programming +- to write our own classes +- to write new classes that inherit from existing classes + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/plotting.rst b/lecture_notes/advanced_python/plotting.rst new file mode 100644 index 0000000..ad246d4 --- /dev/null +++ b/lecture_notes/advanced_python/plotting.rst @@ -0,0 +1,816 @@ +Interactive Plotting +==================== + +We have looked at the basics of Python. In this section we shall look at the +basics of plotting. + +Lets start our IPython interpreter, by + +:: + + $ ipython -pylab + +Pylab is a python library which provides plotting functionality. It also +provides many other important mathematical and scientific functions. After +running ``ipython -pylab`` in your shell if at the top of the output, you see +something like + +:: + + `ERROR: matplotlib could NOT be imported! Starting normal IPython.` + + +Then you have to install ``python-matplotlib`` and run this command again. + +Let us get started directly and try plotting a cosine curve in the range -pi +to pi. + +:: + + p = linspace(-pi,pi,100) + plot(p, cos(p)) + +As you can see we have obtained a cosine curve in the required range. Let's +try and understand what we have done here. + +The variable ``p`` has a hundred points in the range -pi to pi. To see this, +check the documentation of the linspace command. + +:: + + linspace? + +As you can see, it returns ``num`` evenly spaced samples, calculated over the +interval start and stop. + +You can verify this, by looking at the first and last points of ``p`` and the +length of ``p`` + +:: + + print p[0], p[-1], len(p) + +Now, let's clear the plot we obtained and plot a sine curve in the same +range. + +:: + + clf() + plot(p, sin(p)) + +``clf`` command clears the plot, and the plot command following it, plots the +required curve. + +Let's briefly explore the plot window and look at what features it has. + +Firstly, note that moving the mouse around gives us the point where mouse +points at. + +Also we have some buttons the right most among them is for saving the file. + +Left to the save button is the slider button to specify the margins. + +Left to this is zoom button to zoom into the plot. Just specify the region to +zoom into. + +The button left to it can be used to move the axes of the plot. + +The next two buttons with a left and right arrow icons change the state of +the plot and take it to the previous state it was in. It more or less acts +like a back and forward button in the browser. + +The last one is 'home', which returns the plot to the original view. + +Embellishing Plots +================== + +Now that we know how to make simple plots, let us look at embellishing the +plots. We shall look at how to modify the colour, thickness and line-style of +a plot. We shall then learn how to add title to a plot and then look at +adding labels to x and y axes. We shall also look at adding annotations to the plot and setting the limits on the axes. + +Let us decorate the sine curve that we have already plotted. If you have closed that window or your IPython terminal, redo the plot. + +:: + + p = linspace(-pi,pi,100) + plot(p, sin(p)) + + +As we can see, the default colour and the default thickness of the line is as +decided by pylab. Wouldn't it be nice if we could control these parameters in +the plot? This is possible by passing additional arguments to the plot +command. + +The additional argument that we shall be passing in here now is the color +argument. We shall first clear the figure and plot the same in red color. + +:: + + clf() + plot(p, sin(p), 'r') + +As we can see we have the same plot but now in red color. + +To alter the thickness of the line, we use the ``linewidth`` argument +in the plot command. + +:: + + plot(p, cos(p), linewidth=2) + +produces a plot with a thicker line, to be more precise plot with line +thickness 2. + +Occasionally we would also want to alter the style of line. Sometimes all we +want is just a bunch of points not joined. This is possible by passing the +linestyle argument along with or instead of the colour argument. + +:: + + clf() + plot(p, sin(p), '.') + +produces a plot with only points. + +To produce the same plot but now in blue colour, we do + +:: + + clf() + plot(p, sin(p), 'b.') + +Other available options can be seen in the documentation of plot. + +:: + + plot? + +Now that we know how to produce a bare minimum plot with colour, style and +thickness of our interest, we shall look at decorating the plot. + +Let us start with a plot of the function -x^2 + 4x - 5 in the range -2 to 4. + +:: + + x = linspace(-2, 4, 50) + plot(x, -x*x + 4*x - 5, 'r', linewidth=2) + +We now have the plot in a colour and linewidth of our interest. As you can +see, the figure does not have any description describing the plot. + +We will now add a title to the plot by using the ``title`` command. + +:: + + title("Parabolic function -x^2+4x-5") + +The figure now has a title which describes what the plot is. The ``title`` +command as you can see, takes a string as an argument and sets the title +accordingly. + +The formatting in title is messed and it does not look clean. You can imagine +what would be the situation if there were fractions and more complex +functions like log and exp. Wouldn't it be good if there was LaTeX like +formatting? + +That is also possible by adding a $ sign before and after the part of the +string that should be in LaTeX style. For instance, + +:: + + title("Parabolic function $-x^2+4x-5$") + +gives us the polynomial formatted properly. + +Although we have title, the plot is not complete without labelling x and y +axes. Hence we shall label x-axis to "x" and y-axis to "f(x)" :: + + xlabel("x") + +As you can see, ``xlabel`` command takes a string as an argument, +similar to the ``title`` command and sets it as the label to x-axis. + +.. #[See the diff] + +Similarly, + +:: + + ylabel("f(x)") + +sets the name of the y-axis as "f(x)" + +Let us now see how to name or annotate a point on the plot. For example the +point (2, -1) is the local maxima. We would like to name the point +accordingly. We can do this by using + +:: + + annotate("local maxima", xy=(2, -1)) + +As you can see, the first argument to ``annotate`` command is the name we +would like to mark the point as and the second argument is the co-ordinates +of the point at which the name should appear. It is a sequence containing two +numbers. The first is x co-ordinate and second is y co-ordinate. + +As we can see, every annotate command makes a new annotation on the figure. + +Now we have everything we need to decorate a plot. But, it would be nice to +change the limits of the plot area, so that it looks better. + +We shall look at how to get and set them from the script. We shall first get +the existing limits and then change them as required. + +:: + + xlim() + ylim() + +We see that ``xlim`` function returns the current x axis limits and ylim +function returns the current y-axis limits. + +Let us look at how to set the limits. + +:: + + xlim(-4, 5) + +We see the limits of x-axis are now set to -4 and 5. + +Similarly + +:: + + ylim(-15, 2) + +sets the limits of y-axis appropriately. + +Saving to Scripts +================= + +While we are at it, let's look at how to save all the things we typed into +our interpreter into scripts that can be used anytime we like. + +Let's now look at the history of the commands we have typed. The history can +be retreived by using ``%hist`` command. + +:: + + %hist + + +As you can see, it displays a list of recent commands that we typed. Every +command has a number in front, to specify in which order and when it was +typed. + +Please note that there is a % sign before the hist command. This implies that +``%hist`` is a command that is specific to IPython and not available in the +vanilla Python interpreter. These type of commands are called as magic +commands. + +Also note that, the ``%hist`` itself is a command and is displayed as the +most recent command. We should note that anything we type in is stored as +history, irrespective of whether it is a valid command or an error or an +IPython magic command. + +If we want only the recent 5 commands to be displayed, we pass the number as +an argument to ``%hist`` command. + +:: + + %hist 5 + +displays the recent 5 commands, inclusive of the ``%hist`` command. The +default number is 40. + +To list all the commands between 5 and 10, type + +:: + + %hist 5-10 + +Now that we have the history, we would like to save the required lines of +code from history to reproduce the plot of the parabolic function. This is +possible by using the ``%save`` command. + +Before we do that, let us first look at history and identify what lines of +code we require. + +:: + + %hist + +The first command is linspace. But second command is a command that gave us +an error. Hence we do not need second command. The commands from third to +sixth and eighth are required. + +:: + + %save plot_script.py 1 3-6 8 + +The command saves first and then third to sixth and eighth lines of code into +the specified file. + +The first argument to %save is the path of file to save the commands and the +arguments there after are the commands to be saved in the given order. + +Now that we have the required lines of code in a file, let us learn how to +run the file as a python script. We use the IPython magic command ``%run`` to +do this. + +:: + + %run -i plot_script.py + +The script runs but we do not see the plot. This happens because when we are +running a script and we are not in interactive mode anymore. + +Hence on your IPython terminal type + +:: + + show() + +to show the plot. + +The reason for including a ``-i`` after ``run`` is to tell the interpreter +that if any name is not found in script, search for it in the interpreter. +Hence all these ``sin``, ``plot``, ``pi`` and ``show`` which are not +available in script, are taken from the interpreter and used to run the +script. + +Saving Plots +============ + +Let us now learn to save the plots, from the command line, in different +formats. + +Let us plot a sine curve from minus 3pi to 3pi. + +:: + + x = linspace(-3*pi,3*pi,100) + plot(x,sin(x)) + +As, you can see we now have a sine curve. Let's now see how to save the plot. + +For saving the plot, we will use ``savefig()`` function, and it has to be +done with the plot window open. The statement is, :: + + savefig('sine.png') + +Notice that ``savefig`` function takes one argument which is the filename. +The last 3 characters after the ``.`` in the filename is the extension or +type of the file which determines the format in which you want to save. + +Also, note that we gave the full path or the absolute path to which we +want to save the file. + +Here we have used an extension ``.png`` which means the plot gets saved as a +PNG image. + +You can check file which has been saved as ``sine.png`` + +``savefig`` can save the plot in many formats, such as pdf, ps, eps, svg and +png. + + + +Multiple Plots +============== + +Let us now learn, how to draw more than one plot, how to add legends to each +plot to indicate what each plot represents. We will also learn how to switch +between the plots and create multiple plots with different regular axes which +are also called as subplots. + +Let us first create set of points for our plot. For this we will use the +command called linspace:: + + x = linspace(0, 50, 10) + +As we know, x has 10 points in the interval between 0 and 50 both inclusive. + +Now let us draw a plot simple sine plot using these points + +:: + + plot(x, sin(x)) + +This should give us a nice sine plot. + +Oh! wait! It isn't as nice, as we expected. The curve isn't very smooth, why? +In the ``linspace`` command, we chose too few points in a large interval +between 0 and 50 for the curve to be smooth. So now let us use linspace again +to get 500 points between 0 and 50 and draw the sine plot + +:: + + y = linspace(0, 50, 500) + plot(y, sin(y)) + +Now we see a smooth curve. We can also see that, we have two plots, one +overlaid upon another. Pylab overlays plots by default. + +Since, we have two plots now overlaid upon each other we would like to have a +way to indicate what each plot represents to distinguish between them. This +is accomplished using legends. Equivalently, the legend command does this for +us + +:: + + legend(['sine-10 points', 'sine-500 points']) + +Now we can see the legends being displayed for the respective plots. The +legend command takes a single list of parameters where each parameter is the +text indicating the plots in the order of their serial number. + +Additionally, we could give the ``legend`` command an additional argument to +choose the location of the placement, manually. By default, ``pylab`` places +it in the location it thinks is the best. The example below, places it in the +center of the plot. Look at the doc-string of ``legend`` for other locations. + +:: + + legend(['sine-10 points', 'sine-500 points'], loc='center') + +We now know how to draw multiple plots and use legends to indicate which plot +represents what function, but we would like to have more control over the +plots we draw. Like plot them in different windows, switch between them, +perform some operations or labeling on them individually and so on. Let us +see how to accomplish this. Before we move on, let us clear our screen. + +:: + + clf() + +To accomplishing this, we use the figure command + +:: + + x = linspace(0, 50, 500) + figure(1) + plot(x, sin(x), 'b') + figure(2) + plot(x, cos(x), 'g') + +Now we have two plots, a sine plot and a cosine plot in two different +figures. + +The figure command takes an integer as an argument which is the serial number +of the plot. This selects the corresponding plot. All the plot commands we +run after this are applied to the selected plot. In this example figure 1 is +the sine plot and figure 2 is the cosine plot. We can, for example, save each +plot separately + +:: + + savefig('cosine.png') + figure(1) + title('sin(y)') + savefig('sine.png') + +We also titled our first plot as 'sin(y)' which we did not do for the second +plot. + +Let us now do the following. Draw a line of the form y = x as one figure and +another line of the form y = 2x + 3. Switch back to the first figure, +annotate the x and y intercepts. Now switch to the second figure and annotate +its x and y intercepts. Save each of them. + +To solve this problem we should first create the first figure using +the figure command. Before that, let us first run clf command to make +sure all the previous plots are cleared + +:: + + clf() + figure(1) + x = linspace(-5, 5, 100) + plot(x, x) + +Now we can use figure command to create second plotting area and plot +the figure + +:: + + figure(2) + plot(x, ((2 * x) + 3)) + +Now to switch between the figures we can use figure command. So let us +switch to figure 1. We are asked to annotate x and y intercepts of the +figure 1 but since figure 1 passes through origin we will have to +annotate the origin. We will annotate the intercepts for the second +figure and save them as follows + +:: + + figure(1) + annotate('Origin', xy=(0.0, 0.0) + figure(2) + annotate('x-intercept', xy=(0, 3)) + annotate('y-intercept', xy=(0, -1.5)) + savefig('plot2.png') + figure(1) + savefig('plot1.png') + +We can close the figures from the terminal by using the ``close()`` command. + +:: + + close() + close() + +The first ``close`` command closes figure 1, and the second one closes the +figure 2. We could have also use the ``close`` command with an argument +'all', to close all the figures. + +:: + + close('all') + +At times we run into situations where we want to compare two plots and in +such cases we want to draw both the plots in the same plotting area. The +situation is such that the two plots have different regular axes which means +we cannot draw overlaid plots. In such cases we can draw subplots. + +We use subplot command to accomplish this + +:: + + subplot(2, 1, 1) + +``subplot`` command takes three arguments, number of rows, number of columns +and the plot number, which specifies what subplot must be created now in the +order of the serial number. In this case we passed 1 as the argument, so the +first subplot that is top half is created. If we execute the subplot command +as + +:: + + subplot(2, 1, 2) + +the lower subplot is created. Now we can draw plots in each of the subplot +area using the plot command. + +:: + + x = linspace(0, 50, 500) + plot(x, cos(x)) + + subplot(2, 1, 1) + y = linspace(0, 5, 100) + plot(y, y ** 2) + +This created two plots one in each of the subplot area. The top subplot holds +a parabola and the bottom subplot holds a cosine curve. + +As seen here we can use subplot command to switch between the subplot +as well, but we have to use the same arguments as we used to create +that subplot, otherwise the previous subplot at that place will be +automatically erased. It is clear from the two subplots that both have +different regular axes. For the cosine plot x-axis varies from 0 to +100 and y-axis varies from 0 to 1 where as for the parabolic plot the +x-axis varies from 0 to 10 and y-axis varies from 0 to 100 + +Plotting Data +============= + +We often require to plot points obtained from experimental observations, +instead of the analytic functions that we have been plotting, until now. We +shall now learn to read data from files and read it into sequences that can +later be used to plot. + +We shall use the ``loadtxt`` command to load data from files. We will be +looking at how to read a file with multiple columns of data and load each +column of data into a sequence. + +Now, Let us begin with reading the file ``primes.txt``, which contains just a +list of primes listed in a column, using the loadtxt command. The file, in +our case, is present in ``primes.txt``. + +Now let us read this list into the variable ``primes``. + +:: + + primes = loadtxt('primes.txt') + +``primes`` is now a sequence of primes, that was listed in the file, +``primes.txt``. + +We now type, ``print primes`` to see the sequence printed. + +We observe that all of the numbers end with a period. This is so, because +these numbers are actually read as ``floats``. + +Now, let us use the ``loadtxt`` command to read a file that contains two +columns of data, ``pendulum.txt``. This file contains the length of the +pendulum in the first column and the corresponding time period in the second. +Note that ``loadtxt`` needs both the columns to have equal number of rows. + +Let us, now, read the data into the variable ``pend``. Again, it is +assumed that the file is in our current working directory. + +:: + + pend = loadtxt('pendulum.txt') + +Let us now print the variable ``pend`` and see what's in it. + +:: + + print pend + +Notice that ``pend`` is not a simple sequence like ``primes``. It has a +sequence of items in which each item contains two values. Let us use an +additional argument of the ``loadtxt`` command, to read it into two separate, +simple sequences. We add the argument ``unpack=True`` to the ``loadtxt`` +command. + +:: + + L, T = loadtxt('pendulum.txt', unpack=True) + +Let us now, print the variables L and T, to see what they contain. + +:: + + print L + print T + +Notice, that L and T now contain the first and second columns of data +from the data file, ``pendulum.txt``, and they are both simple +sequences. ``unpack=True`` has given us the two columns into two +separate sequences instead of one complex sequence. + +Now that we have the required data in sequences, let us see how to plot it. + +Since we already have the values of L and T as two different sequences, we +now need to calculate T squared. We shall be plotting L vs. T^2 values. + +To obtain the square of sequence T we will use the function ``square`` + +:: + + Tsq = square(T) + +Now to plot L vs T^2 we will simply type + +:: + + plot(L, Tsq, '.') + +For any experimental data, there is always an error in measurements due to +instrumental and human constraints. Now we shall try and take into account +error into our plots. + +We shall read the read the error values from the file ``pendulum_error.txt`` +along with the L and T values. + +:: + + L, T, L_err, T_err = loadtxt('pendulum_error.txt', unpack=True) + + +Now to plot L vs T^2 with an error bar we use the function ``errorbar()`` + +:: + + errorbar(L, Tsq , xerr=L_err, yerr=T_err, fmt='b.') + +This gives a plot with error bar for x and y axis. The dots are of blue +color. The parameters ``xerr`` and ``yerr`` are error on x and y axis and +``fmt`` is the format of the plot. + + +You can explore other options of ``errorbar`` by looking at it's +documentation. + +:: + + errorbar? + + +Other kinds of Plots +==================== + +We shall now briefly look at a few other kinds of plots, namely, the scatter +plot, the pie chart, the bar chart and the log-log plot. + +Let us start with scatter plot. + +In a scatter plot, the data is displayed as a collection of points, each +having the value of one variable determining the position on the horizontal +axis and the value of the other variable determining the position on the +vertical axis. This kind of plot is also called a scatter chart, a scatter +diagram or a scatter graph. + +Now, let us plot a scatter plot showing the percentage profit of a company A +from the year 2000-2010. The data for the same is available in the file +``company-a-data.txt``. + +The data file has two lines with a set of values in each line, the first line +representing years and the second line representing the profit percentages. + +To produce the scatter plot, we first need to load the data from the file +using ``loadtxt``. + +:: + + year,profit = loadtxt('company-a-data.txt', dtype=int) + +By default loadtxt converts the value to float. The ``dtype=type(int())`` +argument in loadtxt converts the value to integer as we require the data as +integers. + +In-order to generate the scatter graph we will use the function ``scatter()`` + +:: + + scatter(year, profit) + +Notice that we passed two arguments to ``scatter()`` function, first one the +values in x-coordinate, year, and the other the values in y-coordinate, the +profit percentage. + +Now let plot a pie chart for the same data. A pie chart or a circle graph is +a circular chart divided into sectors, illustrating proportion. + +Plot a pie chart representing the profit percentage of company A, with the +same data from file ``company-a-data.txt``. We shall reuse the data we have +already read from the file. + +We can plot the pie chart using the function ``pie()``. + +:: + + pie(profit, labels=year) + +Notice that we passed two arguments to the function ``pie()``. First one the +values and the next one the set of labels to be used in the pie chart. + +Now let us move on to the bar charts. A bar chart or bar graph is a chart +with rectangular bars with lengths proportional to the values that they +represent. + +Plot a bar chart representing the profit percentage of company A, with the +same data from file ``company-a-data.txt``. + +We can plot the bar chart using the function ``bar()``. + +:: + + bar(year, profit) + +Note that the function ``bar()`` needs at least two arguments one the values +in x-coordinate and the other values in y-coordinate which is used to +determine the height of the bars. + +Now let us move on to the log-log plot. A log-log graph or a log-log plot is +a two-dimensional graph of numerical data that uses logarithmic scales on +both the horizontal and vertical axes. + +Due to the nonlinear scaling of the axes, a function of the form y = ax^b +will appear as a straight line on a log-log graph. + +Plot a ``log-log`` chart of y=5*x^3 for x from 1-20. + +Before we actually plot let us calculate the points needed for that. + +:: + + x = linspace(1,20,100) + y = 5*x**3 + +Now we can plot the log-log chart using ``loglog()`` function, + +:: + + loglog(x, y) + +For the sake of clarity, let us make a linear plot of x vs. y. + +:: + + plot(x, y) + +Observing the two plots together should give you some clarity about the +``loglog`` plot. + +Help about matplotlib can be obtained from +http://matplotlib.sourceforge.net/contents.html + +That brings us to the end of the discussion on plots and matplotlib. We have +looked a making simple plots, embellishing plots, saving plots, making +multiple plots, plotting data from files, and a few varieties of plots. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + + diff --git a/lecture_notes/advanced_python/rst.rst b/lecture_notes/advanced_python/rst.rst new file mode 100644 index 0000000..fcbd986 --- /dev/null +++ b/lecture_notes/advanced_python/rst.rst @@ -0,0 +1,277 @@ +ReST +---- + +---------------------------- +The Pythonic way to Document +---------------------------- + +.. author: FOSSEE +.. date: 2010-07-22 Thu + + +What is ReST? +------------- + + + Sage Docs - Linear Algebra | Sources + + ReST is a lightweight markup language. + + Developed by the Python community + + Heavily used in documentation of Python code + +Why ReST? +--------- + + + Highly readable source format. + + Easy to learn and write. + + Simple yet Powerful markup that can produce html/LaTeX output. + +Tools used +---------- + + + You will need python-docutils to compile your ReST documents +:: + + sudo apt-get install python-docutils + + + To build websites, look at Sphinx, rest2web, etc. + + rst2html doesn't support math. We shall use Sphinx to see how math works +:: + + sudo apt-get install python-sphinx + +Generating output +----------------- + + + html:: + + rst2html source.rst destination.html + + + LaTeX :: + + rst2latex source.rst destination.tex + + + Slide shows :: + + rst2s5 source.rst destination.html + +Paragraph +--------- + + + The most basic structural element + + Just a chunk of text separated by blank lines. + + Must begin at the left edge margin. + + Indented paragraphs are output as quoted text. + + Example :: + + Sage provides standard constructions from linear algebra, + e.g., the characteristic polynomial, echelon form, trace, + decomposition, etc., of a matrix. + +Section Headings +---------------- + + + Single line of text with adornment + + Adornment is underline alone or an over- and underline + + ``- = ` : ' " ~ ^ _ * + # < >`` can be used for adornment + + All headings with same adornment are at same level + + **NOTE**- The over/under line should be at least as long as the heading + :: + + Linear Algebra + ============== + + Matrix spaces + ------------- + + Sparse Linear Algebra + --------------------- + + +Text Styles +----------- + + ======================= ==================== + Markup text Resulting text + ======================= ==================== + ``*italics*`` *italics* + ``**strong**`` **strong** + ````inline literal```` ``inline literal`` + ======================= ==================== + + + +Code Samples +------------ + + + To include code, end the prior paragraph with =::= + + Code needs to be indented one level + + The code block ends, when text falls back to the previous indentation + + For instance :: + + For example, each of the following is legal :: + + plot(x, y) # plot x and y using default line style and color + plot(x, y, 'bo') # plot x and y using blue circle markers + plot(y) # plot y using x as index array 0..N-1 + plot(y, 'r+') # ditto, but with red plusses + +Math +---- + + + ReST in itself doesn't support math + + Sphinx has support for math using ~jsmath~ or ~pngmath~ + :: + + :math: `3 \times 3` + + .. math:: + + \sum_{n=0}^N x_n = y + +Lists +----- + + + Three flavors - Enumerated, Bulleted, Definition + + Always start as a new paragraph --- preceeded by a new line + + Enumerated + + Number or Letter followed by a =.=, =)= or surrounded by =( )=. + + :: + + 1) Numbers + #) auto numbered + A. Upper case letters + a) lower case letters + i) roman numerals + (I) more roman numerals + + +Lists ... +--------- + + + Bulleted lists + + Start a line with -, + or * + + :: + + * a bullet point using "*" + + - a sub-list using "-" + + + yet another sub-list + + - another item + +Lists ... +--------- + + + Definition Lists + + * Consist of Term, and it's definition. + * Term is one line phrase; Definition is one or more paragraphs + * Definition is indented relative to the term + * Blank lines are not allowed between term and it's definition + + what + Definition lists associate a term with a definition. + +Tables +------ + + + Simple Tables + + * Each line is a row. + * The table ends with ~=~ + * Column Header is specified by using ~=~ + * Cells may span columns; ~-~ is used to specify cells spanning columns. + +:: + + ============ ============ =========== + Header 1 Header 2 Header 3 + ============ ============ =========== + body row 1 column 2 column 3 + body row 2 Cells may span columns. + ------------ ------------------------ + body row 3 column 2 column 3 + ============ ============ =========== + + +Tables... +--------- + +Grid Tables +----------- + +:: + + +------------+------------+-----------+ + | Header 1 | Header 2 | Header 3 | + +============+============+===========+ + body row 1 column 2 column 3 + +------------+------------+-----------+ + body row 2 Cells may span columns. + +------------+------------+-----------+ + body row 3 Cells may - Cells + +------------+ span rows. - contain + body row 4 - blocks. + +------------+------------+-----------+ + +Links +----- + + + External links + + Python_ is my favorite programming language. + +.. _Python: http://www.python.org/ + + + Internal links + + * To generate a link target, add a label to the location + +.. _example: + * Titles & Section headings automatically produce link targets (in ReST) + * Linking to Target + + in ReST :: + + This is an example_ link. + A Title + ======= + + `A Title`_ automatically generates hyperlink targets. + + + in Sphinx :: + + :ref: `This is an example <example>` link. + This is an :ref: `example` link. + + +Footnotes +--------- +:: + + This[#]_ gives auto-numbered[#]_ footnotes. + + This[*]_ gives auto-symbol footnotes[*]_. + + .. [#] First auto numbered footnote + .. [#] Second auto numbered footnote + .. [*] First auto symbol footnote + .. [*] Second auto symbol footnote + + + +References +---------- + + + An Introduction to reStructured Text -- David Goodger + + Quick reStructuredText + + reStructuredText-- Bits and Pieces -- Christoph Reller + + +.. `An Introduction to reStructured Text`: http://docutils.sourceforge.net/docs/ref/rst/introduction.html +.. `Quick reStructuredText`: http://docutils.sourceforge.net/docs/user/rst/quickref.html +.. `reStructuredText-- Bits and Pieces`: http://people.ee.ethz.ch/~creller/web/tricks/reST.html + diff --git a/lecture_notes/advanced_python/sage.rst b/lecture_notes/advanced_python/sage.rst new file mode 100644 index 0000000..46fcef4 --- /dev/null +++ b/lecture_notes/advanced_python/sage.rst @@ -0,0 +1,947 @@ +Sage notebook +============= + +In this section, we will learn what Sage is, what is Sage notebook, how to +start and use the sage notebook. In the notebook we will be specifically +learning how to execute our code, how to write annotations and other +content, typesetting the content and how to use the offline help available. + +To start with, What is Sage? Sage is a free, open-source mathematical +software. Sage can do a lot of math stuff for you including, but not +limited to, algebra, calculus, geometry, cryptography, graph theory among +other things. It can also be used as aid in teaching and research in any of +the areas that Sage supports. So let us start Sage now + +We are assuming that you have Sage installed on your computer now. If not +please visit the page +http://sagemath.org/doc/tutorial/introduction.html#installation for the +tutorial on how to install Sage. + + +Let us now learn how to start Sage. On the terminal type + +:: + + sage + +This should start a new Sage shell with the prompt sage: which looks like +this + +:: + + sage: + +So now we can type all the commands that Sage supports here. But Sage comes +bundled with a much more elegant tool called Sage Notebook. It provides a +web based user interface to use Sage. So once we have a Sage notebook +server up and running, all we need is a browser to access the Sage +functionality. + +We could also use a server run by somebody, else like the official instance +of the Sage server at http://sagenb.org. So all we need is just a browser, +a modern browser, to use Sage and nothing else! The Sage notebook also +provides a convenient way of sharing and publishing our work, which is very +handy for research and teaching. + +However we can also run our own instances of Sage notebook servers on all +the computers we have a local installation of Sage. To start the notebook +server just type + +:: + + notebook() + +on the Sage prompt. This will start the Sage Notebook server. If we are +starting the notebook server for the first time, we are prompted to enter +the password for the admin. Type the password and make a note of it. After +this Sage automatically starts a browser page, with the notebook opened. + +If it doesn't automatically start a browser page check if the Notebook +server started and there were no problems. If so open your browser and in +the address bar type the URL shown in the instructions upon running the +notebook command on the sage prompt. + +If you are not logged in yet, it shows the Notebook home page and textboxes +to type the username and the password. You can use the username 'admin' and +the password you gave while starting the notebook server for the first +time. There are also links to recover forgotten password and to create new +accounts. + +Once we are logged in with the admin account we can see the notebook admin +page. A notebook can contain a collection of Sage Notebook worksheets. + +Worksheet is basically a working area. This is where we enter all the Sage +commands on the notebook. + +The admin page lists all the worksheets created. On the topmost part of +this page we have the links to various pages. + +The home link takes us to the admin home page. The published link takes us +to the page which lists all the published worksheets. The log link has the +complete log of all the actions we did on the notebook. We have the +settings link where we can configure our notebook, the notebook server, +create and mangage accounts. We have a link to help upon clicking opens a +new window with the complete help of Sage. The entire documentation of Sage +is supplied with Sage for offline reference and the help link is the way to +get into it. Then we can report bugs about Sage by clicking on Report a +Problem link and there is a link to sign out of the notebook. + +We can create a new worksheet by clicking New Worksheet link + +Sage prompts you for a name for the worksheet. Let us name the worksheet as +nbtutorial. Now we have our first worksheet which is empty. + +A worksheet will contain a collection of cells. Every Sage command must be +entered in this cell. Cell is equivalent to the prompt on console. When we +create a new worksheet, to start with we will have one empty cell. Let us +try out some math here + +:: + + 2 + 2 + 57.1 ^ 100 + +The hat operator is used for exponentiation. We can observe that only the +output of the last command is displayed. By default each cell displays the +result of only the last operation. We have to use print statement to +display all the results we want to be displayed. + +Now to perform more operations we want more cells. So how do we create a +new cell? It is very simple. As we hover our mouse above or below the +existing cells we see a blue line, by clicking on this new line we can +create a new cell. + +We have a cell, we have typed some commands in it, but how do we evaluate +that cell? Pressing Shift along with Enter evaluates the cell. +Alternatively we can also click on the evaluate link to evaluate the cell + +:: + + matrix([[1,2], [3,4]])^(-1) + +After we create many cells, we may want to move between the cells. To move +between the cells use Up and Down arrow keys. Also clicking on the cell +will let you edit that particular cell. + +To delete a cell, clear the contents of the cell and hit backspace. + +If you want to add annotations in the worksheet itself on the blue line +that appears on hovering the mouse around the cell, Hold Shift and click on +the line. This creates a *What You See Is What You Get* cell. + +We can make our text here rich text. We can make it bold, Italics, we can +create bulleted and enumerated lists in this area + +:: + + This text contains both the **bold** text and also *italicised* + text. + It also contains bulleted list: + * Item 1 + * Item 2 + It also contains enumerate list: + 1. Item 1 + 2. Item 2 + +In the same cell we can display typeset math using the LaTeX like syntax + +:: + + $\int_0^\infty e^{-x} \, dx$ + +We enclose the math to be typeset within $ and $ or $$ and $$ as in LaTeX. + +We can also obtain help for a particular Sage command or function within +the worksheet itself by using a question mark following the command + +:: + + sin? + +Evaluating this cell gives me the entire help for the sin function inline +on the worksheet itself. Similarly we can also look at the source code of +each command or function using double question mark + +:: + + matrix?? + +Sage notebook also provides the feature for autocompletion. To auto-complete +a command type first few unique characters and hit tab key + +:: + + sudo<tab> + +To see all the commands starting with a specific name type those characters +and hit tab + +:: + + plo<tab> + +To list all the methods that are available for a certain variable or a +data-type we can use the variable name followed by the dot to access the +methods available on it and then hit tab + +:: + + s = 'Hello' + s.rep<tab> + +The output produced by each cell can be one of the three states. It can be +either the full output, or truncated output or hidden output. The output +area will display the error if the Sage code we wrote in the cell did not +successfully execute + +:: + + a, b = 10 + +The default output we obtained now is a truncated output. Clicking at the +left of the output area when the mouse pointer turns to hand gives us the +full output, clicking again makes the output hidden and it cycles. + +Lastly, Sage supports a variety of languages and each cell on the worksheet +can contain code written in a specific language. It is possible to instruct +Sage to interpret the code in the language we have written. This can be +done by putting percentage sign(%) followed by the name of the language. +For example, to interpret the cell as Python code we put + +:: + + %python + +as the first line in the cell. Similarly we have: %sh for shell scripting, +%fortran for Fortran, %gap for GAP and so on. Let us see how this works. +Say we have an integer. The type of the integer in default Sage mode is + +:: + + a = 1 + type(a) + + Output: <type 'sage.rings.integer.Integer'> + +We see that Integers are Sage Integers. Now let us put %python as the first +line of the cell and execute the same code snippet + +:: + + %python + a = 1 + type(a) + + Output: <type 'int'> + +Now we see that the integer is a Python integer. Why? Because now we +instructed Sage to interpret that cell as Python code. + +This brings us to the end of the section on using Sage. + +Symbolics +========= + +In this section, we shall learn to define symbolic expressions in Sage, use +built-in constants and functions, perform integration and differentiation +using Sage, define matrices and symbolic functions and simplify and solve +them. + +In addtion to a lot of other things, Sage can do Symbolic Math and we shall +start with defining symbolic expressions in Sage. + +On the sage notebook type + +:: + + sin(y) + +It raises a name error saying that ``y`` is not defined. We need to declare +``y`` as a symbol. We do it using the ``var`` function. + +:: + + var('y') + +Now if you type + +:: + + sin(y) + +Sage simply returns the expression. + +Sage treats ``sin(y)`` as a symbolic expression. We can use this to do +symbolic math using Sage's built-in constants and expressions. + +Let us try out a few examples. + +:: + + var('x, alpha, y, beta') + (x^2/alpha^2)+(y^2/beta^2) + +We have defined 4 variables, ``x``, ``y``, ``alpha`` and ``beta`` and +have defined a symbolic expression using them. + +Here is an expression in ``theta`` + +:: + + var('theta') + sin(theta)*sin(theta)+cos(theta)*cos(theta) + +Sage also provides built-in constants which are commonly used in +mathematics, for instance pi, e, infinity. The function ``n`` gives the +numerical values of all these constants. + +:: + + n(pi) + n(e) + n(oo) + +If you look into the documentation of function ``n`` by doing + +:: + + n? + +You will see what all arguments it takes and what it returns. It will be +very helpful if you look at the documentation of all functions introduced, +in this section. + +Also we can define the number of digits we wish to have in the constants. +For this we have to pass an argument -- digits. + +:: + + n(pi, digits = 10) + +Apart from the constants Sage also has a lot of built-in functions like +``sin``, ``cos``, ``log``, ``factorial``, ``gamma``, ``exp``, ``arcsin`` +etc ... + +Lets try some of them out on the Sage notebook. + +:: + + sin(pi/2) + + arctan(oo) + + log(e,e) + +Given that we have defined variables like x, y etc., we can define an +arbitrary function with desired name + +:: + + var('x') + function('f',x) + +Here f is the name of the function and x is the independent variable . +Now we can define f(x) to be + +:: + + f(x) = x/2 + sin(x) + +Evaluating this function f for the value x=pi returns pi/2. + +:: + + f(pi) + +We can also define functions that are not continuous but defined piece-wise. +Let us define a function which is a parabola between 0 to 1 and a constant +from 1 to 2 . + +:: + + + var('x') + h(x)=x^2 + g(x)=1 + + f=Piecewise([[(0,1),h(x)],[(1,2),g(x)]],x) + f + +We can also define functions convergent series and other series. + +We first define a function f(n) in the way discussed above. + +:: + + var('n') + function('f', n) + + +To sum the function for a range of discrete values of n, we use the +sage function sum. + +For a convergent series , f(n)=1/n^2 we can say + +:: + + var('n') + function('f', n) + f(n) = 1/n^2 + sum(f(n), n, 1, oo) + + +Lets us now try another series + +:: + + + f(n) = (-1)^(n-1)*1/(2*n - 1) + sum(f(n), n, 1, oo) + +This series converges to pi/4. + +Let's now look at some calculus. + +:: + + diff(x**2 + sin(x), x) + +The diff function differentiates an expression or a function. It's first +argument is expression or function and second argument is the independent +variable. + +We have already tried an expression now lets try a function + +:: + + f = exp(x^2) + arcsin(x) + diff(f(x), x) + +To get a higher order differential we need to add an extra third argument +for order + +:: + + diff(f(x), x, 3) + +in this case it is 3. + +Just like differentiation of expression you can also integrate them + +:: + + x = var('x') + s = integral(1/(1 + (tan(x))**2),x) + s + +Many a times we need to find factors of an expression, we can use the +"factor" function + +:: + + y = (x^100 - x^70)*(cos(x)^2 + cos(x)^2*tan(x)^2) + f = factor(y) + +One can simplify complicated expression + +:: + + f.simplify_full() + +This simplifies the expression fully. We can also do simplification of +just the algebraic part and the trigonometric part + +:: + + f.simplify_exp() + f.simplify_trig() + +One can also find roots of an equation by using ``find_root`` function + +:: + + phi = var('phi') + find_root(cos(phi)==sin(phi),0,pi/2) + +Let's substitute this solution into the equation and see we were +correct + +:: + + var('phi') + f(phi)=cos(phi)-sin(phi) + root=find_root(f(phi)==0,0,pi/2) + f.substitute(phi=root) + +as we can see when we substitute the value the answer is almost = 0 showing +the solution we got was correct. + +Lets us now try some matrix algebra symbolically :: + + var('a,b,c,d') + A=matrix([[a,1,0],[0,b,0],[0,c,d]]) + A + +Now lets do some of the matrix operations on this matrix + +:: + A.det() + A.inverse() + + +That brings us to the end of our discussion on symbolics. + +Plotting using Sage +=================== + +In this section we shall look at + + * 2D plotting in SAGE + * 3D plotting in SAGE + +We shall first create a symbolic variable ``x`` + +:: + + x = var('x') + +We shall plot the function ``sin(x) - cos(x) ^ 2`` in the range (-5, 5). + +:: + + plot(sin(x) - cos(x) ^ 2, (x, -5, 5)) + +As we can see, the plot is shown. + +``plot`` command takes the symbolic function as the first argument and the +range as the second argument. + +We have seen that plot command plots the given function on a linear range. + +What if the x and y values are functions of another variable. For instance, +lets plot the trajectory of a projectile. + +A projectile was thrown at 50 m/s^2 and at an angle of 45 degrees from the +ground. We shall plot the trajectory of the particle for 5 seconds. + +These types of plots can be drawn using the parametric_plot function. We +first define the time variable. + +:: + + t = var('t') + +Then we define the x and y as functions of t. + +:: + + f_x = 50 * cos(pi/4) + f_y = 50 * sin(pi/4) * t - 1/2 * 9.81 * t^2 ) + +We then call the ``parametric_plot`` function as + +:: + + parametric_plot((f_x, f_y), (t, 0, 5)) + +And we can see the trajectory of the projectile. + +The ``parametric_plot`` funciton takes a tuple of two functions as the +first argument and the range over which the independent variable varies as +the second argument. + +Now we shall look at how to plot a set of points. + +We have the ``line`` function to achieve this. + +We shall plot sin(x) at few points and join them. + +First we need the set of points. + +:: + + points = [ (x, sin(x)) for x in srange(-2*float(pi), 2*float(pi), 0.75) ] + +``srange`` takes a start, a stop and a step argument and returns a list of +point. We generate list of tuples in which the first value is ``x`` and +second is ``sin(x)``. + +:: + + line(points) + +plots the points and joins them with a line. + +The ``line`` function behaves like the plot command in matplotlib. The +difference is that ``plot`` command takes two sequences while line command +expects a sequence of co-ordinates. + +As we can see, the axes limits are set by SAGE. Often we would want to set +them ourselves. Moreover, the plot is shown here since the last command +that is executed produces a plot. + +Let us try this example + +:: + + plot(cos(x), (x,0,2*pi)) + # Does the plot show up?? + +As we can see here, the plot is not shown since the last command does not +produce a plot. + +The actual way of showing a plot is to use the ``show`` command. + +:: + + p1 = plot(cos(x), (x,0,2*pi)) + show(p1) + # What happens now?? + +As we can see the plot is shown since we used it with ``show`` command. + +``show`` command is also used set the axes limits. + +:: + + p1 = plot(cos(x), (x,0,2*pi)) + show(p1, xmin=0, xmax=2*pi, ymin=-1.2, ymax=1.2) + +As we can see, we just have to pass the right keyword arguments to the +``show`` command to set the axes limits. + +The ``show`` command can also be used to show multiple plots. + +:: + + p1 = plot(cos(x), (x, 0, 2*pi)) + p2 = plot(sin(x), (x, 0, 2*pi)) + show(p1+p2) + +As we can see, we can add the plots and use them in the ``show`` command. + +Now we shall look at 3D plotting in SAGE. + +We have the ``plot3d`` function that takes a function in terms of two +independent variables and the range over which they vary. + +:: + + x, y = var('x y') + plot3d(x^2 + y^2, (x, 0, 2), (y, 0, 2)) + +We get a 3D plot which can be rotated and zoomed using the mouse. + +``parametric_plot3d`` function plots the surface in which x, y and z are +functions of another variable. + +:: + + u, v = var("u v") + f_x = u + f_y = v + f_z = u^2 + v^2 + parametric_plot3d((f_x, f_y, f_z), (u, 0, 2), (v, 0, 2)) + +Using Sage +========== + +In this section we shall quickly look at a few examples of using Sage for +Linear Algebra, Calculus, Graph Theory and Number theory. + +Let us begin with Calculus. We shall be looking at limits, differentiation, +integration, and Taylor polynomial. + +To find the limit of the function x*sin(1/x), at x=0, we say + +:: + + lim(x*sin(1/x), x=0) + +We get the limit to be 0, as expected. + +It is also possible to the limit at a point from one direction. For +example, let us find the limit of 1/x at x=0, when approaching from the +positive side. + +:: + + lim(1/x, x=0, dir='above') + +To find the limit from the negative side, we say, + +:: + + lim(1/x, x=0, dir='below') + +Let us now see how to differentiate, using Sage. We shall find the +differential of the expression ``exp(sin(x^2))/x`` w.r.t ``x``. We shall +first define the expression, and then use the ``diff`` function to obtain +the differential of the expression. + +:: + + var('x') + f = exp(sin(x^2))/x + + diff(f, x) + +We can also obtain the partial differentiation of an expression w.r.t one +of the variables. Let us differentiate the expression ``exp(sin(y - +x^2))/x`` w.r.t x and y. + +:: + + var('x y') + f = exp(sin(y - x^2))/x + + diff(f, x) + + diff(f, y) + +Now, let us look at integration. We shall use the expression obtained from +the differentiation that we did before, ``diff(f, y)`` --- ``e^(sin(-x^2 + +y))*cos(-x^2 + y)/x``. The ``integrate`` command is used to obtain the +integral of an expression or function. + +:: + + integrate(e^(sin(-x^2 + y))*cos(-x^2 + y)/x, y) + +We get back the correct expression. The minus sign being inside or outside +the ``sin`` function doesn't change much. + +Now, let us find the value of the integral between the limits 0 and pi/2. + +:: + + integral(e^(sin(-x^2 + y))*cos(-x^2 + y)/x, y, 0, pi/2) + +Let us now see how to obtain the Taylor expansion of an expression using +sage. Let us obtain the Taylor expansion of ``(x + 1)^n`` up to degree 4 +about 0. + +:: + + var('x n') + taylor((x+1)^n, x, 0, 4) + +This brings us to the end of the features of Sage for Calculus, that we +will be looking at. For more, look at the Calculus quick-ref from the Sage +Wiki. + +Next let us move on to Matrix Algebra. + +Let us begin with solving the equation ``Ax = v``, where A is the matrix +``matrix([[1,2],[3,4]])`` and v is the vector ``vector([1,2])``. + +To solve the equation, ``Ax = v`` we simply say + +:: + + x = solve_right(A, v) + +To solve the equation, ``xA = v`` we simply say + +:: + + x = solve_left(A, v) + +The left and right here, denote the position of ``A``, relative to x. + +Now, let us look at Graph Theory in Sage. + +We shall look at some ways to create graphs and some of the graph families +available in Sage. + +The simplest way to define an arbitrary graph is to use a dictionary of +lists. We create a simple graph by + +:: + + G = Graph({0:[1,2,3], 2:[4]}) + +We say + +:: + + G.show() + +to view the visualization of the graph. + +Similarly, we can obtain a directed graph using the ``DiGraph`` function. + +:: + + G = DiGraph({0:[1,2,3], 2:[4]}) + + +Sage also provides a lot of graph families which can be viewed by typing +``graph.<tab>``. Let us obtain a complete graph with 5 vertices and then +show the graph. + +:: + + G = graphs.CompleteGraph(5) + + G.show() + +Sage provides other functions for Number theory and Combinatorics. Let's +have a glimpse of a few of them. + +:: + + prime_range(100, 200) + +gives primes in the range 100 to 200. + +:: + + is_prime(1999) + +checks if 1999 is a prime number or not. + +:: + + factor(2001) + +gives the factorized form of 2001. + +:: + + C = Permutations([1, 2, 3, 4]) + C.list() + +gives the permutations of ``[1, 2, 3, 4]`` + +:: + + C = Combinations([1, 2, 3, 4]) + C.list() + +gives all the combinations of ``[1, 2, 3, 4]`` + +That brings us to the end of this session showing various features +available in Sage. + +Using Sage to Teach +=================== + +In this section, we shall look at + + * How to use the "@interact" feature of SAGE for better demonstration + * How to use SAGE for collaborative learning + +Let us look at a typical example of demonstrating a damped oscillation. + +:: + + t = var('t') + p1 = plot( e^(-t) * sin(2*t), (t, 0, 15)) + show(p1) + +Now let us reduce the damping factor + +:: + + t = var('t') + p1 = plot(e^(-t/2) * sin(2*t), (t, 0, 15)) + show(p1) + +Now if we want to reduce the damping factor even more, we would be using +e^(-t/3). We can observe that every time we have to change, all we do is +change something very small and re evaluate the cell. + +This process can be simplified, using the ``@interact`` feature of SAGE. + +:: + + @interact + def plot_damped(n=1): + t = var('t') + p1 = plot( e^(-t/n) * sin(2*t), (t, 0, 20)) + show(p1) + +We can see that the function is evaluated and the plot is shown. We can +also see that there is a field to enter the value of ``n`` and it is +currently set to ``1``. Let us change it to 2 and hit enter. + +We see that the new plot with reduced damping factor is shown. Similarly we +can change ``n`` to any desired value and hit enter and the function will +be evaluated. + +This is a very handy tool while demonstrating or teaching. + +Often we would want to vary a parameter over range instead of taking it as +an input from the user. For instance we do not want the user to give ``n`` +as 0 for the damping oscillation we discussed. In such cases we use a range +of values as the default argument. + +:: + + @interact + def plot_damped(n=(1..10)): + t = var('t') + p1 = plot( e^(-t/n) * sin(2*t), (t, 0, 20)) + show(p1) + +We get similar plot but the only difference is the input widget. Here it is +a slider unlike an input field. We can see that as the slider is moved, the +function is evaluated and plotted accordingly. + +Sometimes we want the user to have only a given set of options. We use a +list of items as the default argument in such situations. + +:: + + @interact + def str_shift(s="STRING", shift=(0..8), direction=["Left", "Right"]): + shift_len = shift % len(s) + chars = list(s) + if direction == "Right": + shifted_chars = chars[-shift_len:] + chars[:-shift_len] + else: + shifted_chars = chars[shift_len:] + chars[:shift_len] + print "Actual String:", s + print "Shifted String:", "".join(shifted_chars) + +We can see that buttons are displayed which enables us to select from a +given set of options. + +We have learnt how to use the ``@interact`` feature of SAGE for better +demonstration. We shall look at how to use SAGE worksheets for +collaborative learning. + +The first feature we shall see is the ``publish`` feature. Open a worksheet +and in the top right, we can see a button called ``publish``. Click on that +and we get a confirmation page with an option for re publishing. + +For now lets forget that option and simply publish by clicking ``yes``. The +worksheet is now published. + +Now lets sign out and go to the sage notebook home. We see link to browse +published worksheets. Lets click on it and we can see the worksheet. This +does not require login and anyone can view the worksheet. + +Alternatively, if one wants to edit the sheet, there is a link on top left +corner that enables the user to download a copy of the sheet onto their +home. This way they can edit a copy of the worksheet. + +We have learnt how to publish the worksheets to enable users to edit a +copy. Next, we shall look at how to enable users to edit the actual +worksheet itself. + +Let us open the worksheet and we see a link called ``share`` on the top +right corner of the worksheet. Click the link and we get a box where we can +type the usernames of users whom we want to share the worksheet with. We +can even specify multiple users by seperating their names using commas. +Once we have shared the worksheet, the worksheet appears on the home of +shared users. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/advanced_python/scipy.rst b/lecture_notes/advanced_python/scipy.rst new file mode 100644 index 0000000..fd0508a --- /dev/null +++ b/lecture_notes/advanced_python/scipy.rst @@ -0,0 +1,270 @@ +In this section we shall look at using scipy to do various common +scientific computation tasks. We shall be looking at solving equations +(linear and non-linear) and solving ODEs. We shall also briefly look at +FFTs. + +Solving Equations +================= + +Let us begin with solving equations, specifically linear equations. + +Consider the set of equations, +:: + + 3x + 2y -z = 1, + 2x-2y + 4z = -2, + -x+ 1/2 y-z = 0 + +We shall use the ``solve`` function, to solve the given system of linear +equations. ``solve`` requires the coefficients and the constants to be in +the form of matrices, of the form ``Ax = b`` to solve the system. + +We begin by entering the coefficients and the constants as matrices. + +:: + + A = array([[3,2,-1], + [2,-2,4], + [-1, 0.5, -1]]) + +A is a 3X3 matrix of the coefficients of x, y and z + +:: + + b = array([1, -2, 0]) + +Now, we can use the solve function to solve the given system. + +:: + + x = solve(A, b) + +Type x, to look at the solution obtained. + +The equation is of the form ``Ax = b``, so we verify the solution by +obtaining a matrix product of ``A`` and ``x``, and comparing it with ``b``. +As we have seen earlier, we should use the dot function, for a matrix +product and not the * operator. + +:: + + Ax = dot(A, x) + Ax + +The result ``Ax``, doesn't look exactly like ``b``, but if we carefully +observe, we will see that it is the same as ``b``. To save ourself all this +trouble, we can use the ``allclose`` function. + +``allclose`` checks if two matrices are close enough to each other (with-in +the specified tolerance level). Here we shall use the default tolerance +level of the function. + +:: + allclose(Ax, b) + +The function returns ``True``, which implies that the product of ``A`` & +``x`` is very close to the value of ``b``. This validates our solution. + +Let's move to finding the roots of a polynomial. We shall use the ``roots`` +function for this. + +The function requires an array of the coefficients of the polynomial in the +descending order of powers. Consider the polynomial x^2-5x+6 = 0 + +:: + + coeffs = [1, -5, 6] + roots(coeffs) + +As we can see, roots returns the result in an array. It even works for +polynomials with imaginary roots. + +:: + + roots([1, 1, 1]) + +As you can see, the roots of that equation are complex. + +What if, we want the solution of non linear equations? + +For that we shall use the ``fsolve`` function. We shall use the equation +sin(x)+cos^2(x), as an example. ``fsolve`` is not part of the pylab package +which we imported at the beginning, so we will have to import it. It is +part of ``scipy`` package. Let's import it, + +:: + + from scipy.optimize import fsolve + +We shall look at the details of importing, later. + +Now, let's look at the documentation of fsolve by typing fsolve? + +:: + + fsolve? + +As mentioned in documentation the first argument, ``func``, is a python +function that takes atleast one argument. The second argument, ``x0``, is +the initial estimate of the roots of the function. Based on this initial +guess, ``fsolve`` returns a root. + +Let's define a function called f, that returns the value of +``(sin(x)+cos^2(x))`` evaluated at the input value ``x``. + +:: + + def f(x): + return sin(x)+cos(x)*cos(x) + +We can test our function, by calling it with an argument for which the +output value is known, say x = 0. We can see that + +Let's check our function definition, by calling it with 0 as an argument. + +:: + + f(0) + + +We can see that the output is 1 as expected, since sin(x) + cos^2(x) has a +value of 1, when x = 0. + +Now, that we have our function, we can use ``fsolve`` to obtain a root of +the expression sin(x)+cos^2(x). Let's use 0 as our initial guess. + +:: + + fsolve(f, 0) + +fsolve has returned a root of sin(x)+cos^2(x) that is close to 0. + +That brings us to the end of our discussion on solving equations. We +discussed solution of linear equations, finding roots of polynomials and +non-linear equations. + + +ODEs +==== + +Let's see how to solve Ordinary Differential Equations (ODEs), using +Python. Let's consider the classic problem of the spread of an epidemic in +a population, as an example. + +This is given by the ordinary differential equation ``dy/dt = ky(L-y)`` +where L is the total population and k is an arbitrary constant. + +For our problem, let us use L=250000, k=0.00003. Let the boundary condition +be y(0)=250. + +We shall use the ``odeint`` function to solve this ODE. As before, this +function resides in a submodule of SciPy and doesn't come along with Pylab. +We import it, +:: + + from scipy.integrate import odeint + +We can represent the given ODE as a Python function. This function takes +the dependent variable y and the independent variable t as arguments and +returns the ODE. + +:: + + def epid(y, t): + k = 0.00003 + L = 250000 + return k*y*(L-y) + +Independent variable t can be assigned the values in the interval of 0 and +12 with 60 points using linspace: + + In []: t = linspace(0, 12, 60) + +Now obtaining the solution of the ode we defined, is as simple as calling +the Python's ``odeint`` function which we just imported + +:: + + y = odeint(epid, 250, t) + +We can plot the the values of y against t to get a graphical picture our ODE. + +:: + + plot(y, t) + +Let's now try and solve an ODE of second order. Let's take the example of a +simple pendulum. + +The equations can be written as a system of two first order ODEs + + d(theta)/dt = omega + +and + + d(omega)/dt = - g/L sin(theta) + +Let us define the boundary conditions as: at t = 0, theta = theta-naught = +10 degrees and omega = 0 + +Let us first define our system of equations as a Python function, +``pend_int``. As in the earlier case of single ODE we shall use ``odeint`` +function to solve this system of equations. + +:: + + def pend_int(initial, t): + theta = initial[0] + omega = initial[1] + g = 9.81 + L = 0.2 + f=[omega, -(g/L)*sin(theta)] + return f + +It takes two arguments. The first argument itself containing two dependent +variables in the system, theta and omega. The second argument is the +independent variable t. + +In the function we assign the first and second values of the initial +argument to theta and omega respectively. Acceleration due to gravity, as +we know is 9.81 meter per second sqaure. Let the length of the the pendulum +be 0.2 meter. + +We create a list, f, of two equations which corresponds to our two ODEs, +that is ``d(theta)/dt = omega`` and ``d(omega)/dt = - g/L sin(theta)``. We +return this list of equations f. + +Now we can create a set of values for our time variable t over which we need +to integrate our system of ODEs. Let us say, + +:: + + t = linspace(0, 20, 100) + +We shall assign the boundary conditions to the variable initial. + +:: + + initial = [10*2*pi/360, 0] + +Now solving this system is just a matter of calling the odeint function with +the correct arguments. + +:: + + pend_sol = odeint(pend_int, initial,t) + + plot(pend_sol) + +This gives us 2 plots, omega vs t and theta vs t. + +That brings us to the end of our discussion on ODEs and solving them in +Python. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/basic_python/exercises.rst b/lecture_notes/basic_python/exercises.rst new file mode 100644 index 0000000..3c02c56 --- /dev/null +++ b/lecture_notes/basic_python/exercises.rst @@ -0,0 +1,180 @@ +Exercises +========= + +1. Round a float to the nearest integer using ``int()``. + +#. What does this do? round(amount * 10)/10.0. How to round it to the nearest + 5 paise? + +#. Print out the fibonacci sequence less than 30 + +#. Write a program that prints the numbers from 1 to 100. But for multiples + of three print "Fizz" instead of the number and for the multiples of five + print "Buzz". For numbers which are multiples of both three and five print + "FizzBuzz". This is famously known as the FizzBuzz test. + +#. Write a program that displays all three digit numbers that are equal to + the sum of the cubes of their digits. That is, print numbers :math:`$abc$` + that have the property :math:`$abc = a^3 + b^3 + c^3$` These are called + :math:`$Armstrong$` numbers. + +#. Collatz sequence + + #. Start with an arbitrary (positive) integer. + #. If the number is even, divide by 2; if the number is odd multiply by 3 + and add 1. + #. Repeat the procedure with the new number. + #. There is a cycle of 4, 2, 1 at which the procedure loops. + + Write a program that accepts the starting value and prints out the Collatz + sequence. + +#. Kaprekar's constant + + #. Take a four digit number–with at least two digits different. + #. Arrange the digits in ascending and descending order, giving A and D + respectively. + #. Leave leading zeros in A! + #. Subtract A from D. + #. With the result, repeat from step 2. + + Write a program to accept a 4-digit number and display the progression to + Kaprekar’s constant. + +#. Write a program that prints the following pyramid on the screen. + + :: + + 1 + 2 2 + 3 3 3 + 4 4 4 4 + + + The number of lines must be obtained from the user as input. When can your + code fail? + +#. Write a function to return the gcd of two numbers. + +#. Write a program to find Primitive Pythagorean Triads A pythagorean triad + :math:`$(a,b,c)$` has the property :math:`$a^2 + b^2 = c^2$`. By primitive + we mean triads that do not ‘depend’ on others. For example, (4,3,5) is a + variant of (3,4,5) and hence is not primitive. And (10,24,26) is easily + derived from (5,12,13) and should not be displayed by our program. Write a + program to print primitive pythagorean triads. The program should generate + all triads with a, b values in the range 0—100 + +#. Write a program that generates a list of all four digit numbers that have + all their digits even and are perfect squares. For example, the output + should include 6400 but not 8100 (one digit is odd) or 4248 (not a perfect + square). + +#. The aliquot of a number is defined as: the sum of the *proper* of the + number. + + For example, the ``aliquot(12) = 1 + 2 + 3 + 4 + 6 = 16``. + + Write a function that returns the aliquot number of a given number. + +#. A pair of numbers (a, b) is said to be *amicable* if the aliquot number of + a is b and the aliquot number of b is a. + + Example: ``220, 284`` + + Write a program that prints all five digit amicable pairs. + +#. Given an empty chessboard and one Bishop placed in any square, say (r, c), + generate the list of all squares the Bishop could move to. + + +#. Write a program to display the following pyramid. The number of lines + in the pyramid should not be hard-coded. It should be obtained from + the user. The pyramid should appear as close to the centre of the + screen as possible. + + :: + + * + *** + ***** + ******* + + +#. Write a program to display the following pyramid. The number of lines + in the pyramid should not be hard-coded. It should be obtained from + the user. The pyramid should appear as close to the centre of the + screen as possible. + + :: + + * + * * + * * * + * * * * + + +#. Write a program to display the following pyramid. The number of lines + has to be a parameter obtained from the user. The pyramid must appear + aligned to the left edge of the screen. + + :: + + 1 + 2 2 + 3 3 3 + 4 4 4 4 + + +#. Write a program to display the following pyramid. The number of lines + has to be a parameter obtained from the user. The pyramid must appear + aligned to the left edge of the screen. + + :: + + 1 + 2 4 + 3 6 9 + 4 8 12 16 + 5 10 15 20 25 + + +#. Write a program to display the following output. The last number + where the program will stop printing has to be a parameter obtained + from the user. The pyramid must appear aligned to the left edge of + the screen. Note that depending on the last number, the base of the + pyramid may be smaller than the line above it. + + :: + + 1 + 2 3 + 4 5 6 + 7 8 9 10 + 11 12 + +#. Given a string like, "1, 3-7, 12, 15, 18-21", produce the list + ``[1,3,4,5,6,7,12,15,18,19,20,21]`` + +#. You are given date strings of the form “29, Jul 2009â€, or “4 January + 2008â€. In other words a number a string and another number, with a comma + sometimes separating the items.Write a function that takes such a string + and returns a tuple (yyyy, mm, dd) where all three elements are ints. + +#. Count word frequencies in a file. + +#. Given a dictionary of the names of students and their marks, identify how + many duplicate marks are there? and what are these? + +#. Given a string of the form "4-7, 9, 12, 15" find the numbers missing in + this list for a given range. + + + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + diff --git a/lecture_notes/basic_python/func.rst b/lecture_notes/basic_python/func.rst new file mode 100644 index 0000000..bd9074b --- /dev/null +++ b/lecture_notes/basic_python/func.rst @@ -0,0 +1,420 @@ +Functions +========= + +We are now going to learn about functions in Python --- how to define +them, passing arguments to them, docstrings, and return values. + +While writing code, fewer lines of code is a good thing, since it reduces the +scope of error. Also, we would like to reduce duplication of code and +abstract out pieces of code, wherever possible. Functions allow us to do all +of this. + +Now let us at functions in a greater detail, + +Consider a mathematical function ``f(x) = x^2``. Here ``x`` is a variable and +with different values of ``x`` the value of function will change. When ``x`` +is one f(1) will return the value 1 and f(2) will return us the value 4. Let +us now see how to define the function f(x) in Python. + +:: + + def f(x): + return x*x + +Well that defined the function, so before learning what we did let us +see if it returns the expected values, try, + +:: + + f(1) + f(2) + +Yes, it returned 1 and 4 respectively. And now let us see what we did. We +wrote two lines: The first line ``def f(x):`` defines the name of the +function and specifies the parameters to the function. The second line +specifies what the function is supposed to return. ``def`` is a keyword and +``f`` is the name of the function and ``x`` the parameter of the function. + +You can also have functions without any arguments. + +Let us define a new function called ``greet`` which will print ``Hello +World``. + +:: + + def greet(): + print "Hello World!" + +now try calling the function, + +:: + + greet() + +Well that is a function which takes no arguments. Also note that it is not +mandatory for a function to return values. The function ``greet`` isn't +taking any argument. Also, it is not returning any value explicitly. But for +such functions, Python returns a ``None`` object by default + +Now let us see how to write functions with more than one argument. + +:: + + def avg(a, b): + return (a + b)/2 + +If we want a function to accept more arguments, we just list them separated +with a comma between the parenthesis after the function's name in the ``def`` +line. + +It is always a good practice to document the code that we write, and +for a function we define we should write an abstract of what the +function does, and that is called a docstring. + +Let us modify the function ``avg`` and add docstring to it. + +:: + + def avg(a,b): + """ avg takes two numbers as input, and + returns their average""" + + return (a+b)/2 + +Note that docstrings are entered in the line immediately after the function +definition and put as a triple quoted string. + +Now we try this in the IPython interpreter, + +:: + + avg? + +it displays the docstring as we gave it. Thus docstring has practical utility +also, and is not just a good "practice". + +Try to do this, + +:: + + greet? + +It doesn't have a docstring associated with it. Also we cannot infer anything +from the function name, and thus we are forced to read the code to understand +about the function. + +Let's now write a function named ``circle`` which returns the area and +perimeter of a circle given radius ``r``. + +The function needs to return two values instead of just one which was being +returned until now. + +:: + + def circle(r): + """returns area and perimeter of a circle given radius r""" + pi = 3.14 + area = pi * r * r + perimeter = 2 * pi * r + return area, perimeter + +Similarly, you could have a function returning three or four or any number of +values. A Python function can return any number of values and there is not +restriction on it. + +Let us call the function ``circle`` as, + +:: + + a, p = circle(6) + print a + print p + +Let us now do a little code reading, as opposed to writing. + +What does the function ``what`` do? + +:: + + def what( n ): + if n < 0: n = -n + while n > 0: + if n % 2 == 1: + return False + n /= 10 + return True + +The function returns ``True`` if all the digits of the number ``n`` are even, +otherwise it returns ``False``. + +:: + + def even_digits( n ): + """returns True if all the digits in the number n are even, + returns False if all the digits in the number n are not even""" + if n < 0: n = -n + while n > 0: + if n % 2 == 1: + return False + n /= 10 + return True + + +Now one more code reading exercise, + +What does this function ``what`` do? + +:: + + def what( n ): + i = 1 + while i * i < n: + i += 1 + return i * i == n, i + +The function returns ``True`` and the square root of ``n`` if n is a perfect +square, otherwise it returns ``False`` and the square root of the next +perfect square. + +:: + + def is_perfect_square( n ): + """returns True and square root of n, if n is a perfect square, + otherwise returns False and the square root of the + next perfect square""" + i = 1 + while i * i < n: + i += 1 + return i * i == n, i + +Default & Keyword Arguments +--------------------------- + +Let us now look at specifying default arguments to functions when defining +them and calling functions using keyword arguments. + +Let's use the ``round`` function as an example to understand what a default +value of an argument means. Let's type the following expressions in the +terminal. + +:: + + round(2.484) + + round(2.484, 2) + +Both the first expression and the second are calls to the ``round`` function, +but the first calls it with only one argument and the second calls it with +two arguments. By observing the output, we can guess that the first one is +equivalent to call with the second argument being 0. 0 is the default value +of the argument. + +:: + + s.split() # split on spaces. + s.split(';') # split on ';' + + range(10) # returns a list with numbers from 0 to 9 + range(1, 10) # returns a list with numbers from 1 to 9 + range(1, 10, 2) # returns a list with odd numbers from 1 to 9 + +Let's now define a simple function that uses default arguments. We define a +simple function that prints a welcome message to a person, given a greeting +and his/her name. + +:: + + def welcome(greet, name="World"): + print greet, name + +Let us first call the function with two arguments, one for ``greet`` and +other for ``name``. + +:: + + welcome("Hi", "Guido") + +We get the expected welcome message, "Hi Guido". + +Now let us call the function with just one argument "Hello". + +:: + + welcome("Hello") + +"Hello" is treated as the ``greet`` and we get "Hello World" as the output. +"World" is the default value for the argument ``name``. + +If we redefined the function ``welcome``, by interchanging it's arguments and +placed the ``name`` argument with it's default value of "World" before the +``greet`` argument, what happens? + +:: + + def welcome(name="World", greet): + print greet, name + +We get an error that reads ``SyntaxError: non-default argument follows +default argument``. When defining a function all the argument with default +values should come at the end. + +Let us now learn what keyword arguments or named arguments are. We shall +refer to them as keyword arguments, henceforth. + +When you are calling functions in Python, you don't need to remember the +order in which to pass the arguments. Instead, you can use the name of the +argument to pass it a value. Let us understand this using the ``welcome`` +function that we have been using all along. Let us call it in different ways +and observe the output to see how keyword arguments work. + +:: + + welcome() + welcome("Hello", "James") + + welcome("Hi", name="Guido") + +When no keyword is specified, the arguments are allotted based on their +position. So, "Hi" is the value of the argument ``greet`` and name is passed +the value "Guido". + +:: + + welcome(name="Guido", greet="Hey! ") + +When keyword arguments are used, the arguments can be called in any order. + +:: + + welcome(name="Guido", "Hey") + +This call returns an error that reads, ``non keyword arg after keyword arg``. +Python expects all the keyword to be present towards the end. + +That brings us to the end of what we wanted to learn about ``keyword`` +arguments. + +Before defining a function of your own, make sure that you check the standard +library, for a similar function. Python is popularly called a "Batteries +included" language, for the huge library that comes along with it. Refer +`here <http://docs.python.org/library/functions.html>`_. + +Variable scope +-------------- + +Before we end the discussion on functions, a short note on the scope of +variables in Python is in order. + +Arguments passed to a function are local. They are not available outside of +the function. + +:: + + def change(q): + q = 10 + print q + + change(1) + print q + +The variables used inside a function definition are considered to be "local" +variables and their existence is restricted to within the function. Global +variables are those variables, which are accessible from anywhere within a +Python program. + +Variables that are assigned to within a function, are treated as local +variables by default. + +:: + + n = 5 + + def change(): + n = 10 + print n + + change() + print n + +As you can see, the value of n hasn't changed after the function ``change`` +was called. + +To assign to global variables (or variables which can be accessed from +outside the function), we need to use the global statement. We could redefine +the change function as shown below. + +:: + + def change(): + global n + n = 10 + print n + + change() + print n + +There is a subtle difference in the behavior when we assign not directly to a +variable, but a list element or a list slice etc. In this case, Python looks +up for the name, from the innermost scope (the function), outwards, until it +finds the name. + +For example + +:: + + name = ['Mr.', 'Steve', 'Gosling'] + + def change_name(): + name[0] = 'Dr.' + + change_name() + print name + +As, you can see, even though there was no variable ``name`` within the scope +of the function ``change_name``, calling it has changed the list ``name``. + +Also, let us tweak the examples above to learn about the way values are +passed to functions. + +:: + + n = 5 + + def change(n): + n = 10 + print "n = %s, inside change" %n + + change(n) + print n + +:: + + name = ['Mr.', 'Steve', 'Gosling'] + + def change_name(n): + n[0] = 'Dr.' + print "n = %s, inside change_name" %n + + change_name(n) + print name + + +Notice that the value of ``n`` does not get changed in the first case, +because numbers are immutable datatypes and they cannot be modified. In the +second case when a list was passed to the function ``change_name``, it is +changed because a list is mutable and it's first element is chaned by the +function. + +That brings us to the end of this section on functions. We have learnt how to +define functions, use them with default values and keyword arguments. We have +also looked briefly at variables and their scopes. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + + diff --git a/lecture_notes/basic_python/handout.rst b/lecture_notes/basic_python/handout.rst new file mode 100644 index 0000000..37554ab --- /dev/null +++ b/lecture_notes/basic_python/handout.rst @@ -0,0 +1,10 @@ +============== + Basic Python +============== + +.. include :: intro.rst +.. include :: strings_loops_lists.rst +.. include :: io_files_parsing.rst +.. include :: func.rst +.. include :: tuples_dicts_sets.rst +.. include :: exercises.rst diff --git a/lecture_notes/basic_python/intro.rst b/lecture_notes/basic_python/intro.rst new file mode 100644 index 0000000..3953db0 --- /dev/null +++ b/lecture_notes/basic_python/intro.rst @@ -0,0 +1,584 @@ +Introduction +============ + +Python in a powerful, high-level, interpreted and multi-platform programming +language with an elegant and readable syntax, efficient high-level data +structures and a simple but effective approach to object programming. + +Python is easy to learn. It has been designed to help the programmer +concentrate on solving the problem at hand and not worry about the +programming language idiosyncrasies. Programmers often fall in love with +Python, for the increased productivity it brings. + +Python was created by Guido van Rossum. The idea of Python was conceived in +December 1989. The name Python comes from the 70s comedy series "Monty +Python's Flying Circus" and has nothing to do with the reptilian. + +Why Python? +----------- + +* Python code is extremely readable. It has no braces and semi-colons and + uses indentation, instead, for defining code blocks. This forces the + programmers to write readable code. + +* It is interactive and the interactive environment offers a very fast + edit-test-debug cycle. + +* It has a good set of high-level data structures and has been designed to + let the programmer focus on the problem, rather than worry about the + idiosyncrasies of the language. + +* It handles memory management and takes the burden, of allocating and + de-allocating memory to variables off the programmer. + +* It is a Batteries included language. It comes with a huge standard library + that allows us to do a wide range of tasks. + +* It is object-oriented. + +* It interfaces with other programming languages such as C, C++ and FORTRAN. + This allows us to use legacy code available in these languages. + +* It not as fast as some of the compiled languages like C or C++. But, we + think that the programmer's time is more valuable than machine time. Given + the flexibility and power that Python gives the programmer, Python is a + valuable tool to learn. + + +The Interpreter +=============== + +Let us get our hands dirty, right away. Typing ``python`` at the terminal, +will start up the Python interpreter. You should see something like this, if +you do have Python installed. + +:: + + Python 2.7.1 (r271:86832, Feb 21 2011, 01:28:26) + [GCC 4.5.2 20110127 (prerelease)] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + >>> + +The first line shows the version of Python that we are using. In this example +the version of Python being used is 2.7.1 + +``>>>`` is called the prompt and it implies that the interpreter is ready and +waiting for your command! + +Let's write our first line of Python code, the ubiquitous ``Hello World``. + +:: + + >>> print 'Hello, World!' + Hello, World! + +Typing ``print 'Hello World'`` and hitting enter, printed out the words +*Hello World*. + +Let us now exit the interpreter. Hitting ``Ctrl-D``, exits the python +interpreter. + +Now we shall learn to use IPython, an enhanced interpreter, instead of the +vanilla interpreter, which we just saw. + +A note on Versions +------------------ + +Before we continue, a not on the versions of Python is in order. Python +currently has two stable branches or versions, 2.x and 3.x. 3.x branch was +created with the idea of cleaning up some areas of Python, to make it more +consistent, without bothering about backward compatibility with older +versions. So, 3.x is not compatible with 2.x, and is deemed to be the future +of Python. But, we shall use 2.x for this course, since the ecosystem around +3.x is still growing and a lot of packages don't yet work with Python 3.x. + +IPython - An enhanced interactive Python interpreter +---------------------------------------------------- + +IPython is an enhanced Python interpreter that provides features like +tabcompletion, easier access to help and lot of other functionality which are +not available in the vanilla Python interpreter. + +invoking IPython +~~~~~~~~~~~~~~~~ + +First let us see how to invoke the ``ipython`` interpreter. + +We type +:: + + ipython + +at the terminal prompt to invoke the ipython interpreter. + +The prompt is now, ``In [1]:`` instead of the ``>>>`` in the vanilla Python +interpreter. We also get the same information about the version of Python +installed. But additionally, we get some IPython help information, instead of +the vanilla interpreter's help. + +``In`` stands for input and the number in the brackets indicates the number +of the current command in this session. We shall see how it's useful in a +short while. + +If you get an error saying something like ``ipython is not installed``, +install it and continue with the course. + +Let's try out the same ``Hello World`` in ``ipython``. + +:: + + print 'Hello World!' + +Now, to quit the ipython interpreter, type Ctrl-D. You are prompted asking if +you really want to exit, type y to say yes and quit ipython. + +Start ipython again, as you did before. + +History and Arrow Keys +~~~~~~~~~~~~~~~~~~~~~~ + +Now let us see, how we can type some commands into the interpreter. + +Start with the simplest thing, addition. + +Let's type + +:: + + 1 + 2 + +at the prompt. IPython promptly gives back the output as 3. Notice +that the output is displayed with an ``Out[1]`` indication. + +Let's try out few other mathematical operations. + +:: + + 5 - 3 + 7 - 4 + 6 * 5 + +Now let's ``print 1+2``. Instead of typing the whole thing, we make use of +the fact that IPython remembers the history of the commands that you have +already used. We use the up arrow key to go back the command ``1+2``. We then +use the left-arrow key to navigate to the beginning of the line and add the +word ``print`` and a space. Then hit enter and observe that the interpreter +prints out the value as 3, without the Out[] indication. + +Now, let's change the previous command ``print 1+2`` to ``print 10*2``. We +use the up arrow again to navigate to the previous command and use the left +arrow key to move the cursor on to the + symbol and then use the delete key +to remove it and type 0 and * to change the expression as required. We hit +enter to see the output of ``print``. + +Tab-completion +~~~~~~~~~~~~~~ + +Now, let's say we want to use the function ``round``. We type ``ro`` at the +prompt and hit the tab key. As you can see, IPython completes the command. +This feature is called the tab-completion. + +Now, we remove all the characters and just type ``r`` and then hit tab. +IPython does not complete the command since there are many possibilities. It +just lists out all the possible completions. + +Now, let's see what these functions are used for. We will use the help +features of ipython to find this out. + +Help using ? +~~~~~~~~~~~~ + +To get the help of any function, we first type the function, ``abs`` in our +case and then add a ? at the end and hit enter. + +As the documentation says, ``abs`` accepts a number as an input and returns +it's absolute value. + +We say, + +:: + + abs(-19) + + abs(19) + +We get 19, as expected, in both the cases. + +Does it work for decimals (or floats)? Let's try typing abs(-10.5) and we do +get back 10.5. + +Let us look at the documentation of the ``round`` function. + +:: + + round? + +If you notice, there are extra square brackets around the ``ndigits``. This +means that ``ndigits`` is optional and 0 is the default value. Optional +parameters are shown in square brackets anywhere in Python documentation. + +The function ``round``, rounds a number to a given precision. + +:: + + round(2.48) + round(2.48, 1) + round(2.48, 2) + + round(2.484) + round(2.484, 1) + round(2.484, 2) + +We get 2.0, 2.5 and 2.48, which are what we expect. + +Interrupting +~~~~~~~~~~~~ + +Let's now see how to correct typing errors that we make while typing at the +terminal. As already shown, if we haven't hit the enter key already, we could +navigate using the arrow keys and make deletions using delete or backspace +key and correct the errors. + +Let's now type ``round(2.484`` and hit enter, without closing the +parenthesis. We get a prompt with dots. This prompt is the continuation +prompt of ``ipython``. It appears, the previous line is incomplete in some +way. We now complete the command by typing, the closing parenthesis and +hitting enter. We get the expected output of 2.5. + +In other instances, if we commit a typing error with a longer and more +complex expression and end up with the continuation prompt, we can type +Ctrl-C to interrupt the command and get back the ``ipython`` input prompt. + +For instance, + +:: + + round(2.484 + ^C + + round(2.484, 2) + + +Now that we know how to use the interpreter, we shall move look at the basic +data-types Python provides, and basic operators. + +Basic Datatypes and Operators +============================= + +Python provides the following basic datatypes. + + * Numbers + + * int + * float + * complex + + * Boolean + * Sequence + + * Strings + * Lists + * Tuples + + +Numbers +------- + +We shall start with exploring the Python data types in the domain of numbers. + +There are three built-in data types in python to represent numbers, namely: + + * int + * float + * complex + +Let us first talk about ``int`` + +:: + + a = 13 + a + + +Now, we have our first ``int`` variable ``a``. + +To verify this, we say + +:: + + type(a) + <type 'int'> + +``int`` data-type can hold integers of any size lets see this by an example. + +:: + + b = 99999999999999999999 + b + +As you can see, even when we put a value of 9 repeated 20 times Python did +not complain. + +Let us now look at the ``float`` data-type. Decimal numbers in Python are +represented by the ``float`` data-type + +:: + + p = 3.141592 + p + +If you notice the value of output of ``p`` isn't exactly equal to ``p``. This +is because floating point values have a fixed precision (or bit-length) and +it is not possible to represent all numbers within the given precision. Such +numbers are approximated and saved. This is why we should never rely on +equality of floating point numbers in a program. + +Finally, let us look at the ``complex`` data-type. + +:: + + c = 3+4j + +gives us a complex number, ``c`` with real part 3 and imaginary part 4. + +To get the real and imaginary parts of ``c``, we say + +:: + + c.real + c.imag + +Note that complex numbers are a combination of two floats, i.e., the real and +the imaginary parts, 3 and 4 are floats and not integers. + +:: + + type(c.real) + type(c.imag) + +We can get the absolute value of c, by + +:: + + abs(c) + +Let's now look at some operators common operations on these data-types. + +:: + + 23 + 74 + 23 - 56 + 45 * 76 + + 8 / 3 + 8.0 / 3 + +The first division, 8/3 is an integer division and results in an integer +output. In the second division, however, the answer is a float. To avoid +integer division, at least one of the operands should be a float. + +``%`` is used for the modulo operation. + +:: + + 87 % 6 + +and ``**`` is for exponentiation. + +:: + + 7 ** 8 + +All of the above operations can be performed with variables, as well. + +:: + + a = 23 + b = 74 + a * b + + c = 8 + d = 8.0 + f = c / 3 + g = d / 3 + +In the last two commands, the results of the operations are being assigned to +new variables. + +In case, we wish to assign the result of an operation on the +variable to itself, we can use a special kind of assignment. + +:: + + c /= 3 + +is the same as + +:: + + c = c / 3 + +Booleans +-------- + +Now let us look at the Boolean data-type. + +:: + + t = True + +creates a boolean variable ``t``, whose value is ``True``. Note that T in +true is capitalized. + +You can apply different Boolean operations on ``t`` now. + +For example + +:: + + f = not t + f + f or t + f and t + +What if you want to use multiple operators? Here's an example. + +:: + + (f and t) or t + +Note that we have used parenthesis, to explicitly state what we want to do. +We are not going to discuss operator precedence and shall use parenthesis, +when using multiple operators. + +The following expression, for instance is different from the one above. + +:: + + f and (t or t) + +Sequences +--------- + +Let's now discuss the sequence data types in Python. The data-types which +hold a bunch of elements in them, in a sequential order are called sequence +data-types. The elements can be accessed using their position in the +sequence. + +The sequence datatypes in Python are - + + * str + * list + * tuple + +:: + + greet_str = "hello" + +``greet_str`` is now a string variable with the value ``hello`` + +Anything within quotes is a string. + +Items enclosed in square brackets separated by commas constitute a list. + +:: + + num_list = [1, 2, 3, 4, 5, 6, 7, 8] + num_list + +To create a tuple we use parentheses ('(') instead of square brackets ('[') + +:: + + num_tuple = (1, 2, 3, 4, 5, 6, 7, 8) + +Operations on sequences +~~~~~~~~~~~~~~~~~~~~~~~ + +Due to their sequential nature, there are certain kind of operations, which +can be performed on all of them. + +Firstly, accessing elements. Elements in sequences can be accessed using +indexes. + +:: + + num_list[2] + num_tuple[2] + greet_str[2] + +As you can see, indexing starts from 0. + +Secondly, you can add two sequences of the same type, to each other to give +new sequences. + +:: + + num_list + [3, 4, 5, 6] + greet_str + " world!" + + +Thirdly, you can get the length of a sequence, by using the ``len`` function. + +:: + + len(num_list) + len(greet_str) + + +Fourthly, we can check the containership of an element using the ``in`` +keyword + +:: + + 3 in num_list + 'h' in greet_str + 'w' in greet_str + 2 in num_tuple + +We see that it gives True and False accordingly. + +Next, we can find the maximum and minimum elements from a sequence. + +:: + + max(num_tuple) + min(greet_str) + +As a consequence of their order, we can access a group of elements in a +sequence. They are called called slicing and striding. + +First lets discuss slicing, on the list ``num_list``. We can access a part of +this sequence by slicing the sequence. Lets say we want elements starting +from 2 and ending in 5. + +:: + + num_list[1:5] + +Note that the elements starting from the first index to the last one, the +last one not included are being returned. We shall look at the details, +later. + +Striding is similar to slicing except that the step size here is not one. + +:: + + num_list[1:8:2] + + +The colon two added in the end signifies all the alternate elements. This is +why we call this concept striding because we move through the list with a +particular stride or step. The step in this example being 2. + +This brings us to the end of our discussion on basic data-types and +operations on them. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + diff --git a/lecture_notes/basic_python/io_files_parsing.rst b/lecture_notes/basic_python/io_files_parsing.rst new file mode 100644 index 0000000..6bbc2e4 --- /dev/null +++ b/lecture_notes/basic_python/io_files_parsing.rst @@ -0,0 +1,386 @@ +I/O +=== + +Input and Output are used in almost every program, we write. We shall now +learn how to + + * Output data + * Take input from the user + +Let's start with printing a string. + +:: + + a = "This is a string" + a + print a + + +``print a``, obviously, is printing the value of ``a``. + +As you can see, even when you type just ``a``, the value of ``a`` is shown. +But there is a difference. + +Typing ``a`` shows the value of ``a`` while ``print a`` prints the string. +This difference becomes more evident when we use strings with newlines in +them. + +:: + + b = "A line \n New line" + b + print b + +As you can see, just typing ``b`` shows that ``b`` contains a newline +character. While typing ``print b`` prints the string and hence the newline. + +Moreover when we type just ``a``, the value ``a`` is shown only in +interactive mode and does not have any effect on the program while running it +as a script. + +We shall look at different ways of outputting the data. + +``print`` statement in Python supports string formatting. Various arguments +can be passed to print using modifiers. + +:: + + x = 1.5 + y = 2 + z = "zed" + print "x is %2.1f y is %d z is %s" %(x, y, z) + +As you can see, the values of x, y and z are substituted in place of +``%2.1f``, ``%d`` and ``%s`` respectively. + +We can also see that ``print`` statement prints a new line character +at the end of the line, everytime it is called. This can be suppressed +by using a "," at the end ``print`` statement. + +Let us see this by typing out following code on an editor as ``print_example.py`` + +Open an editor, like ``scite``, ``emacs`` or ``vim`` and type the following. + +:: + + print "Hello" + print "World" + + print "Hello", + print "World" + +Now we run the script using ``%run /home/fossee/print_example.py`` in the +interpreter. As we can see, the print statement when used with comma in the +end, prints a space instead of a new line. + +Note that Python files are saved with an extension ``.py``. + +Now we shall look at taking input from the user. We will use the +``raw_input`` for this. + +Let's type + +:: + + ip = raw_input() + +The cursor is blinking indicating that it is waiting for input. We now type +some random input, + +:: + + an input + +and hit enter. + +Now let us see what is the value of ip by typing. + +:: + + ip + +We can see that it contains the string "an input" + +Note that raw_input always gives us a string. For example + + +:: + + c = raw_input() + 5.6 + c + +Now let us see the type of c. + +:: + + type(c) + +We see that c is a string. This implies that anything you enter as input, +will be taken as a string no matter what you enter. + +``raw_input`` can also display a prompt to assist the user. + +:: + + name = raw_input("Please enter your name: ") + +prints the string given as argument and then waits for the user input. + +Files +===== + +We shall, now, learn to read files, and do some basic actions on the file, +like opening and reading a file, closing a file, iterating through the file +line-by-line, and appending the lines of a file to a list. + +Let us first open the file, ``pendulum.txt`` present in ``/home/fossee/``. +The file can be opened using either the absolute path or relative path. In +all of these examples we shall assume that our present working directory is +``/home/fossee/`` and hence we only need to specify the file name. To check +the present working directory, we can use the ``pwd`` command and to change +our working directory we can use the ``cd`` command. + +:: + + pwd + cd /home/fossee + +Now, to open the file + +:: + + f = open('pendulum.txt') + +``f`` is called a file object. Let us type ``f`` on the terminal to +see what it is. + +:: + + f + +The file object shows, the file which is open and the mode (read or write) in +which it is open. Notice that it is open in read only mode, here. + +We shall first learn to read the whole file into a single variable. Later, we +shall look at reading it line-by-line. We use the ``read`` method of ``f`` to +read, all the contents of the file into the variable ``pend``. + +:: + + pend = f.read() + +Now, let us see what is in ``pend``, by typing + +:: + + print pend + +We can see that ``pend`` has all the data of the file. Type just ``pend`` to +see more explicitly, what it contains. + +:: + + pend + +We can split the variable ``pend`` into a list, ``pend_list``, of the lines +in the file. + +:: + + pend_list = pend.splitlines() + + pend_list + +Now, let us learn to read the file line-by-line. But, before that we will +have to close the file, since the file has already been read till the end. + +Let us close the file opened into f. + +:: + + f.close() + +Let us again type ``f`` on the prompt to see what it shows. + +:: + + f + +Notice, that it now says the file has been closed. It is a good programming +practice to close any file objects that we have opened, after their job is +done. + +Let us, now move on to reading files line-by-line. + +To read the file line-by-line, we iterate over the file object line-by-line, +using the ``for`` command. Let us iterate over the file line-wise and print +each of the lines. + +:: + + for line in open('pendulum.txt'): + print line + +As we already know, ``line`` is a dummy variable, sometimes called the loop +variable, and it is not a keyword. We could have used any other variable +name, but ``line`` seems meaningful enough. + +Instead of just printing the lines, let us append them to a list, +``line_list``. We first initialize an empty list, ``line_list``. + +:: + + line_list = [ ] + +Let us then read the file line-by-line and then append each of the lines, to +the list. We could, as usual close the file using ``f.close`` and re-open it. +But, this time, let's leave alone the file object ``f`` and directly open the +file within the for statement. This will save us the trouble of closing the +file, each time we open it. + +:: + + for line in open('pendulum.txt'): + line_list.append(line) + +Let us see what ``line_list`` contains. + +:: + + line_list + +Notice that ``line_list`` is a list of the lines in the file, along with the +newline characters. If you noticed, ``pend_list`` did not contain the newline +characters, because the string ``pend`` was split on the newline characters. + +Let us now look at how to parse data, learn some string operations to parse +files and get data out of them, and data-type conversions. + +We have a file containing a huge number of records. Each record corresponds +to the information of a student. + +:: + + A;010002;ANAND R;058;037;42;35;40;212;P;; + + +Each record consists of fields seperated by a ";". The first record is region +code, then roll number, then name, marks of second language, first language, +maths, science and social, total marks, pass/fail indicatd by P or F and +finally W if withheld and empty otherwise. + +Our job is to calculate the arithmetic mean of all the maths marks in the +region B. + +Now what is parsing data. + +From the input file, we can see that the data we have is in the form of text. +Parsing this data is all about reading it and converting it into a form which +can be used for computations -- in our case, sequence of numbers. + +Let us learn about tokenizing strings or splitting a string into smaller +units or tokens. Let us define a string first. + +:: + + line = "parse this string" + +We are now going to split this string on whitespace. + +:: + + line.split() + +As you can see, we get a list of strings. Which means, when ``split`` is +called without any arguments, it splits on whitespace. In simple words, all +the spaces are treated as one big space. + +``split`` also can split on a string of our choice. This is acheived by +passing that as an argument. But first lets define a sample record from the +file. + +:: + + record = "A;015163;JOSEPH RAJ S;083;042;47;AA;72;244;;;" + record.split(';') + +We can see that the string is split on ';' and we get each field seperately. +We can also observe that an empty string appears in the list since there are +two semi colons without anything in between. + +To recap, ``split`` splits on whitespace if called without an argument and +splits on the given argument if it is called with an argument. + +Now that we know how to split a string, we can split the record and retrieve +each field seperately. But there is one problem. The region code "B" and a +"B" surrounded by whitespace are treated as two different regions. We must +find a way to remove all the whitespace around a string so that "B" and a "B" +with white spaces are dealt as same. + +This is possible by using the ``strip`` method of strings. Let us define a +string, + +:: + + word = " B " + word.strip() + +We can see that strip removes all the whitespace around the sentence. + +The splitting and stripping operations are done on a string and their result +is also a string. Hence the marks that we have are still strings and +mathematical operations are not possible on them. We must convert them into +numbers (integers or floats), before we can perform mathematical operations +on them. + +We have seen that, it is possible to convert float into integers using +``int``. We shall now convert strings into floats. + +:: + + mark_str = "1.25" + mark = float(mark_str) + type(mark_str) + type(mark) + +We can see that string, ``mark_str`` is converted to a ``float``. We can +perform mathematical operations on them now. + +Now that we have all the machinery required to parse the file, let us solve +the problem. We first read the file line by line and parse each record. We +see if the region code is B and store the marks accordingly. + +:: + + math_B = [] # an empty list to store the marks + for line in open("sslc1.txt"): + fields = line.split(";") + + reg_code = fields[0] + reg_code_clean = reg_code.strip() + + math_mark_str = fields[5] + math_mark = float(math_mark_str) + + if reg_code == "B": + math_B.append(math_mark) + + +Now we have all the maths marks of region "B" in the list math_marks_B. To +get the mean, we just have to sum the marks and divide by the length. + +:: + + math_B_mean = sum(math_B) / len(math_B) + math_B_mean + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + + diff --git a/lecture_notes/basic_python/module_plan.rst b/lecture_notes/basic_python/module_plan.rst new file mode 100644 index 0000000..e4d1cbd --- /dev/null +++ b/lecture_notes/basic_python/module_plan.rst @@ -0,0 +1,83 @@ +Basic Python +============ + +Module Objectives +----------------- + +After successfully completing this module a participant will be able to: + +* Write Python scripts to perform simple string processing or + mathematical tasks {Ap} +* Read and understand simple procedural Python programs {Ap} + ++---------+------------------------------+----------+ +| Session | Topic | Duration | ++---------+------------------------------+----------+ +| 1 | Introduction to Python | 5 min | +| | | | +| | Python Interpreter | 20 min | +| | - getting started | | +| | - IPython introduction | | +| | | | +| | Basic Data-types | 25 min | +| | - Numbers | | +| | - Booleans | | +| | - Sequences | | +| | | | ++---------+------------------------------+----------+ +| 2 | Strings | 20 min | +| | - Creation | | +| | - Operations | | +| | - Accessing elements | | +| | - immutability | | +| | - methods | | +| | | | +| | Conditionals | 10 min | +| | - if, if-else, if-elif-else | | +| | - Ternary operator | | +| | - pass | | +| | | | +| | Loops | 10 min | +| | - while | | +| | - for | | +| | | | +| | Lists | 20 min | +| | - Creation | | +| | - Operations | | +| | - Accessing elements | | +| | - adding & removing | | +| | - sorting | | ++---------+------------------------------+----------+ +| 3 | I/O | 10 min | +| | - print x & print x, | | +| | - string formatting | | +| | - raw_input | | +| | | | +| | Files | 20 min | +| | - opening | | +| | - reading | | +| | - tokenization | | +| | | | +| | Functions | 30 min | +| | - definition | | +| | - doc-strings | | +| | - code reading | | +| | - default arguments | | +| | - keyword arguments | | +| | - variable scope | | ++---------+------------------------------+----------+ +| 4 | Tuples | 10 min | +| | - packing, unpacking | | +| | - swapping | | +| | | | +| | Dictionaries | 15 min | +| | - creating | | +| | - Accessing elements | | +| | - Adding & removing elements | | +| | - containership | | +| | - keys and values | | +| | | | +| | Sets | 10 min | +| | - creating | | +| | - operations | | ++---------+------------------------------+----------+ diff --git a/lecture_notes/basic_python/strings_loops_lists.rst b/lecture_notes/basic_python/strings_loops_lists.rst new file mode 100644 index 0000000..b894f5b --- /dev/null +++ b/lecture_notes/basic_python/strings_loops_lists.rst @@ -0,0 +1,768 @@ +Strings +======= + +We looked at strings, when looking at the sequence data-types of Python. We +shall now look at them in a greater detail. + +So, what are strings? In Python anything within either single quotes or +double quotes or triple single quotes or triple double quotes are strings. + +:: + + 'This is a string' + "This is a string too' + '''This is a string as well''' + """This is also a string""" + 'p' + "" + +Note that it really doesn't matter how many characters are present in the +string. The last example is a null string or an empty string. + +Having more than one control character to define strings is handy when one of +the control characters itself is part of the string. For example:: + + "Python's string manipulation functions are very useful" + +By having multiple control characters, we avoid the need for escaping +characters -- in this case the apostrophe. + +The triple quoted strings let us define multi-line strings without using any +escaping. Everything within the triple quotes is a single string no matter +how many lines it extends + +:: + + """Having more than one control character to define + strings come as very handy when one of the control + characters itself is part of the string.""" + +We can assign this string to any variable + +:: + + a = 'Hello, World!' + +Now ``a`` is a string variable. A string is a sequence of characters, as we +have already seen. In addition string is an immutable collection. So all the +operations that are applicable to any other immutable collection in Python +works on string as well. So we can add two strings + +:: + + a = 'Hello' + b = 'World' + c = a + ', ' + b + '!' + +We can add string variables as well as the strings themselves all in the same +statement. The addition operation performs the concatenation of two strings. + +Similarly we can multiply a string with an integer + +:: + + a = 'Hello' + a * 5 + +gives another string in which the original string 'Hello' is repeated +5 times. + +Let's now look at accessing individual elements of strings. Since, strings +are collections we can access individual items in the string using the +subscripts + +:: + + a[0] + +gives us the first character in the string. The indexing starts from 0 +for the first character and goes up to n-1 for the last character. We +can access the strings from the end using negative indices + +:: + + a[-1] + +gives us the last element of the string and + +:: + + a[-2] + +gives us second element from the end of the string + +Let us attempt to change one of the characters in a string:: + + a = 'hello' + a[0] = 'H' + +As said earlier, strings are immutable. We cannot manipulate a string. +Although there are some methods which let us manipulate strings, we will look +at them in the advanced session on strings. In addition to the methods that +let us manipulate the strings we have methods like split which lets us break +the string on the specified separator, the join method which lets us combine +the list of strings into a single string based on the specified separator. + +Let us now learn to manipulate strings, specifically slicing and reversing +them, or replacing characters, converting from upper to lower case and +vice-versa and joining a list of strings. + +Let us consider a simple problem, and learn how to slice strings and get +sub-strings. + +Let's say the variable ``week`` has the list of the names of the days of the +week. + +:: + + week = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] + + +Now given a string ``s``, we should be able to check if the string is a +valid name of a day of the week or not. + +:: + + s = "saturday" + + +``s`` could be in any of the forms --- sat, saturday, Sat, Saturday, +SAT, SATURDAY. For now, shall now be solving the problem only for the forms, +sat and saturday. We shall solve it for the other forms, at the end of +the tutorial. + +So, we need to check if the first three characters of the given string +exists in the variable ``week``. + +As, with any of the sequence data-types, strings can be sliced into +sub-strings. To get the first three characters of s, we say, + +:: + + s[0:3] + +Note that, we are slicing the string from the index 0 to index 3, 3 +not included. + +:: + + s = "saturday" + s[:3] + +Now, we just check if that substring is present in the variable ``week``. + +:: + + s[:3] in week + +Let us now consider the problem of finding out if a given string is +palindromic or not. First of all, a palindromic string is a string that +remains same even when it has been reversed. + +Let the string given be ``malayalam``. + +:: + + s = "malayalam" + +Now, we need to compare this string with it's reverse. + +Again, we will use a technique common to all sequence data-types, +[::-1] + +So, we obtain the reverse of s, by simply saying, + +:: + + s[::-1] + +Now, to check if the string is ``s`` is palindromic, we say +:: + + s == s[::-1] + +As, expected, we get ``True``. + +Now, if the string we are given is ``Malayalam`` instead of ``malayalam``, +the above comparison would return a False. So, we will have to convert the +string to all lower case or all upper case, before comparing. Python provides +methods, ``s.lower`` and ``s.upper`` to achieve this. + +Let's try it out. +:: + + s = "Malayalam" + + s.upper() + + s + +As you can see, s has not changed. It is because, ``upper`` returns a new +string. It doesn't change the original string. + +:: + + s.lower() + + s.lower() == s.lower()[::-1] + +So, as you can see, now we can check for presence of ``s`` in ``week``, in +whichever format it is present -- capitalized, or all caps, full name or +short form. + +We just convert any input string to lower case and then check if it is +present in the list ``week``. + +Now, let us consider another problem. We often encounter e-mail id's which +have @ and periods replaced with text, something like info[at]fossee[dot]in. +We now wish to get back proper e-mail addresses. + +Let's say the variable email has the email address. + +:: + + email = "info[at]fossee[dot]in" + +Now, we first replace the ``[at]`` with the ``@``, using the replace method +of strings. + +:: + + email = email.replace("[at]", "@") + print email + + email = email.replace("[dot]", ".") + print email + +Now, let's look at another interesting problem where we have a list of e-mail +addresses and we wish to obtain one long string of e-mail addresses separated +by commas or semi-colons. + +:: + + email_list = ["info@fossee.in", "enquiries@fossee.in", "help@fossee.in"] + +Now, if we wish to obtain one long string, separating each of the +email id by a comma, we use the join operator on ``,``. + +:: + + email_str = ", ".join(email_list) + print email_str + +Notice that the email ids are joined by a comma followed by a space. + +That brings us to the end of our discussion on strings. Let us now look at +conditionals. + +Conditionals +============ + +Whenever we have two possible states that can occur depending on a whether a +certain condition we can use if/else construct in Python. + +For example, say, we have a variable ``a`` which stores integers and we are +required to find out whether ``a`` is even or odd. an even number or an odd +number. Let's say the value of ``a`` is 5, now. + +:: + + a = 5 + +In such a case we can write the if/else block as + +:: + + if a % 2 == 0: + print "Even" + else: + print "Odd" + +If ``a`` is divisible by 2, i.e., the result of "a modulo 2" is 0, it prints +"Even", otherwise it prints "Odd". + +Note that in such a case, only one of the two blocks gets executed depending +on whether the condition is ``True`` or ``False``. + +There is a very important sytactic element to understand here. Every code +block begins with a line that ends with a ``:``, in this example the ``if`` +and the ``else`` lines. Also, all the statements inside a code block are +intended by 4 spaces. Returning to the previous indentation level, ends the +code block. + +The if/else blocks work for a condition, which can take one of two states. +What do we do for conditions, which can take more than two states? + +Python provides if/elif/else blocks, for such conditions. Let us take an +example. We have a variable ``a`` which holds integer values. We need to +print "positive" if ``a`` is positive, "negative" if it is negative or "zero" +if it is 0. + +Let us use if/elif/else ladder for it. For the purposes of testing our +code let us assume that the value of a is -3 + +:: + + a = -3 + + if a > 0: + print "positive" + elif a < 0: + print "negative" + else: + print "zero" + +All the syntax and rules as said for if/else statements hold. The only +addition here is the ``elif`` statement which can have another condition of +its own. + +Here too, exactly one block of code is executed -- the block of code which +first evaluates to ``True``. Even if there is a situation where multiple +conditions evaluate to True all the subsequent conditions other than the +first one which evaluates to True are neglected. Consequently, the else block +gets executed if and only if all the conditions evaluate to False. + +Also, the ``else`` block in both if/else statement and if/elif/else is +optional. We can have a single if statement or just if/elif statements +without having else block at all. Also, there can be any number of elif's +within an if/elif/else ladder. For example + +:: + + if user == 'admin': + # Do admin operations + elif user == 'moderator': + # Do moderator operations + elif user == 'client': + # Do customer operations + +is completely valid. Note that there are multiple elif blocks and there +is no else block. + +In addition to these conditional statements, Python provides a very +convenient ternary conditional operator. Let us take the following example +where we have a score string, which can either be a number in the range 0 to +100 or the string 'AA', if the student is absent. We wish to convert the +score string, into an integer, whenever possible. If the score string is +'AA', we wish to make the corresponding value 0. Let us say the string score +is stored in score_str variable. We can do it using an ``if-else`` construct +as below + +:: + + if score_str != 'AA': + score = int(score_str) + else: + score = 0 + +The same thing can be done using a ternary operator, which reads more natural +and has greater brevity. + +:: + + score = int(score_str) if score_str != 'AA' else 0 + +Moving on, there are certain situations where we will have no operations or +statements within a block of code. For example, we have a code where we are +waiting for the keyboard input. If the user enters "c", "d" or "x" as the +input we would perform some operation nothing otherwise. In such cases "pass" +statement comes very handy. + +:: + + a = raw_input("Enter 'c' to calculate and exit, 'd' to display the existing + results exit and 'x' to exit and any other key to continue: ") + + if a == 'c': + # Calculate the marks and exit + elif a == 'd': + # Display the results and exit + elif a == 'x': + # Exit the program + else: + pass + +In this case "pass" statement acts as a place holder for the block of code. +It is equivalent to a null operation. It literally does nothing. It can used +as a place holder when the actual code implementation for a particular block +of code is not known yet but has to be filled up later. + +That brings us to the end of our discussion of conditionals. + +Loops +===== + +We shall now, look at ``while`` and ``for`` loops. We shall look at how to +use them, how to break out of them, or skip some iterations in loops. + +We shall first begin with the ``while`` loop. The ``while`` loop is used for +repeated execution as long as a condition is ``True``. + +Let us print the squares of all the odd numbers less than 10, using the +``while`` loop. + +:: + + i = 1 + + while i<10: + print i*i + i += 2 + +This loop prints the squares of the odd numbers below 10. + +The ``while`` loop, repeatedly checks if the condition is true and executes +the block of code within the loop, if it is. As with any other block in +Python, the code within the ``while`` block is indented to the right by 4 +spaces. + +Let us now solve the same problem of printing the squares of all odd numbers +less than 10, using the ``for`` loop. The ``for`` loop iterates over a list +or any other sequential data type. + +:: + + for n in [1, 2, 3]: + print n + +Each of the elements of the list, gets printed. The variable ``n``, called +the loop variable, successively takes the value of each of the elements in +the list, in each iteration. + +Now, we could solve the problem of calculating the squares, by + +:: + + for n in [1, 3, 5, 7, 9]: + print n*n + +But, it is "unfair" to generate the list by hand. So, we use the ``range`` +function to get a list of odd numbers below 10, and then iterate over it and +print the required stuff. + +:: + + for n in range(1, 10, 2): + print n*n + +The first argument to the ``range`` function is the start value, the second +is the stop value and the third is the step-size. The ``range`` function +returns a list of values from the start value to the stop value (not +included), moving in steps of size given by the step-size argument. + +Also, The start and the step values are optional. For instance, the code +below prints numbers from 0 to 9. + +:: + + for n in range(10): + print n + +Let us now look at how to use the keywords, ``pass``, ``break`` and +``continue``. + +As we already know, ``pass`` is just a syntactic filler. It is used +for the sake of completion of blocks, that do not have any code within +them. + +:: + + for n in range(2, 10, 2): + pass + +``break`` is used to break out of the innermost loop. The ``while`` +loop to print the squares of all the odd numbers below 10, can be +modified using the ``break`` statement, as follows +:: + + i = 1 + + while True: + print i*i + i += 2 + if i<10: + break + +``continue`` is used to skip execution of the rest of the loop on this +iteration and continue to the end of this iteration. + +Say, we wish to print the squares of all the odd numbers below 10, which are +not multiples of 3, we would modify the ``for`` loop as follows. + +:: + + for n in range(1, 10, 2): + if n%3 == 0: + continue + print n*n + +This brings us to the end of the section on loops. We have learned how to use +the ``for`` and ``while`` loops. + +Lists +===== + +We have already seen lists as a kind of sequence data-type. We shall look at +them in greater detail, now. + +We will first create an empty list with no elements. + +:: + + empty = [] + type(empty) + +This is an empty list without any elements. + +Let's now define a non-empty list. + +:: + + p = ['spam', 'eggs', 100, 1.234] + +Thus the simplest way of creating a list is typing out a sequence of +comma-separated values (or items) between two square brackets. + +As we can see lists can contain different kinds of data. They can be +heterogeneous. In the previous example 'spam' and 'eggs' are strings whereas +100 and 1.234 are integer and float respectively. Below, is another example. + +:: + + q = [[4, 2, 3, 4], 'and', 1, 2, 3, 4] + +As you already know, we access an element of a list using its index. Index of +the first element of a list is 0. + +:: + p[0] + p[1] + p[3] + + +List elements can also be accessed using negative indexing. p[-1] +gives the last element of p. + +:: + p[-1] + +As you can see you get the last element which is 1.234. + +Similarly, -2 gives the second to last element and -4 gives the fourth from +the last which, in this case, is the first element. + +:: + + p[-2] + p[-4] + +Using ``len`` function we can check the number of elements in the list +p. + +:: + + len(p) + +We can append elements to the end of a list using the method append. + +:: + + p.append('onemore') + p + p.append([1, 6]) + p + +As we can see ``p`` is appended with 'onemore' and [1, 6] at the end. + +Just like we can append elements to a list we can also remove them. There are +two ways of doing it. First, is by using the ``del`` command and the index of +the element. + +:: + + del p[1] + + + +will delete the element at index 1, i.e the second element of the list, +'eggs'. + +The other way is removing element by choosing the item. Let's say one wishes +to delete 100 from p list the syntax of the command would be + +:: + + p.remove(100) + +but what if there were two 100's. To check that lets do a small +experiment. + +:: + + p.append('spam') + p + p.remove('spam') + p + +If we check now we will see that the first occurence 'spam' is removed and +therefore `remove` removes the first occurence of the element in the sequence +and leaves others untouched. + +Another other basic operation that we can perform on lists is concatenation +of two or more lists. We can combine two lists by using the "plus" operator. +Say we have + +:: + + a = [1, 2, 3, 4] + b = [4, 5, 6, 7] + a + b + +When we concatenate lists using the "plus" operator we get a new list. We can +store this list in a new variable + +:: + + c = a + b + c + +It is important to observe that the "plus" operator always returns a new list +without altering the lists being concatenated in any way. + +Let us now look at slicing and striding on lists. Let's create a list primes. + +:: + + primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] + +To obtain all the primes between 10 and 20 from the above list of primes we +say + +:: + + primes[4:8] + +This gives us all the elements in the list starting from the element with the +index 4, which is 11 in our list, upto the element with index 8 (not +included). + +:: + + primes[0:4] + +will give us the primes below 10. Recall that the element with the index 4 is +not included in the slice that we get. + +By default the slice fetches all the elements between start and stop (stop +not-included). But, Python also provides the functionality to specify a step +size, when picking elements. Say, we have + +:: + + num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] + +If we want to obtain all the odd numbers less than 10 from the list +``num`` we have to start from element with index 1 upto the index 10 in +steps of 2 + +:: + + num[1:10:2] + +When no step is specified, it is assumed to be 1. Similarly, there are +default values for start and stop indices as well. If we don't specify the +start index it is implicitly taken as the first element of the list + +:: + + num[:10] + +This gives us all the elements from the beginning upto the 10th element but +not including the 10th element in the list "num". Similary if the stop index +is not specified it is implicitly assumed to be the end of the list, +including the last element of the list + +:: + + num[10:] + +gives all the elements starting from the 10th element in the list +"num" upto the final element including that last element. Now + +:: + + num[::2] + +gives us all the even numbers in the list "num". + +We know that a list is a collection of data. Whenever we have a collection we +run into situations where we want to sort the collection. Lists support sort +method which sorts the list in-place + +:: + + a = [5, 1, 6, 7, 7, 10] + a.sort() + +Now the contents of the list ``a`` will be + +:: + + a + [1, 5, 6, 7, 7, 10] + +As the sort method sorts the elements of a list, the original list we had is +overwritten or replaced. We have no way to obtain the original list back. One +way to avoid this is to keep a copy of the original list in another variable +and run the sort method on the list. + +However, Python also provides a built-in function called sorted which sorts +the list which is passed as an argument to it and returns a new sorted list + +:: + + a = [5, 1, 6, 7, 7, 10] + sorted(a) + +We can store this sorted list another list variable + +:: + + sa = sorted(a) + +Python also provides the reverse method which reverses the list in-place + +:: + + a = [1, 2, 3, 4, 5] + a.reverse() + +reverses the list ``a`` and stores the reversed list inplace i.e. in ``a`` +itself. Let's see the list ``a`` + +:: + + a + [5, 4, 3, 2, 1] + +But again the original list is lost. + +To reverse a list, we could use striding with negative indexing. + +:: + + a[::-1] + +We can also store this new reversed list in another list variable. + +That brings us to the end of our discussion on lists. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + + diff --git a/lecture_notes/basic_python/tuples_dicts_sets.rst b/lecture_notes/basic_python/tuples_dicts_sets.rst new file mode 100644 index 0000000..ff722fd --- /dev/null +++ b/lecture_notes/basic_python/tuples_dicts_sets.rst @@ -0,0 +1,426 @@ +We shall now look at a few more datatypes available in Python, namely, +tuples, dictionaries and sets. Let us start with tuples. + +Tuples +====== + +We shall learn + + * what are tuples + * their similarities and dissimilarities with lists + * why are they needed + +Let's get started by defining a tuple. A tuple is defined by enclosing +parentheses around a sequence of items seperated by commas. It is similar to +defining a list except that parentheses are used instead of square brackets. + +:: + + t = (1, 2.5, "hello", -4, "world", 1.24, 5) + t + +defines a tuple. + +It is not always necessary to use parenthesis around a ``tuple`` + +:: + a = 1, 2, 3 + a + (1, 2, 3) + + b = 1, + b + (1,) + +The items in the tuple are indexed using numbers and can be accessed by using +their position. + +:: + + t[3] + +prints -4 which is the fourth item of the tuple. + +:: + + t[1:5:2] + +prints the corresponding slice + +This is the behaviour similar as to lists. But the difference can be seen +when we try to change an element in the tuple. + +:: + + t[2] = "Hello" + +We can see that, it raises an error saying tuple does not support item +assignment. Tuples are immutable, and cannot be changed after creation. + +Then, what's the use of tuples? + +We shall understand that soon. But let us look at a simple problem of +swapping values. + +``a = 5`` and ``b = 7``. swap the values of a and b + +We define the two values + +:: + + a = 5 + b = 7 + + a + b + +Traditionally, we swap them using a temporary variable. + +:: + + temp = a + a = b + b = temp + + a + b + +The Python way, would be + +:: + + a + b + + a, b = b, a + + a + b + +We see that the values are swapped. This idiom works for different data-types +also. + +:: + + a = 2.5 + b = "hello" + + a + b + +Moreover this type of behaviour is something that feels natural and you'd +expect to happen. + +This is possible because of the immutability of tuples. This process is +called tuple packing and unpacking. + +Let us first see what is tuple packing. Type + +:: + + 5, + +What we see is a tuple with one element. + +:: + + 5, "hello", 2.5 + +Now it is a tuple with three elements. + +So when we are actually typing two or more elements seperated by commas, +those elements are packed into a tuple. + +When you type +:: + + a, b = b, a + +First the values of b and a are packed into a tuple on the right side and then +unpacked into the variables a and b. + +Immutability of tuples ensures that the values are not changed during the +packing and unpacking. + +That brings us to the end of our discussion of tuples. Let us now look at +dictionaries. + +Dictionaries +============ + +A dictionary in general, are designed to be able to look up meanings of +words. Similarly, the Python dictionaries are also designed to look up for a +specific key and retrieve the corresponding value. Dictionaries are data +structures that provide key-value mappings. Dictionaries are similar to lists +except that instead of the values having integer indexes, dictionaries have +keys or strings as indexes. + +We shall now look at creating dictionaries, accessing elements of +dictionaries, checking for presence of elements and iterating over the +elements. + +Let us start by creating an empty dictionary, type the following in +your IPython interpreter. + +:: + + mt_dict = {} + +Notice that curly braces are used define dictionaries. + +Now let us see how to create a non-empty dictionary, + +:: + + extensions = {'jpg' : 'JPEG Image', + 'py' : 'Python script', + 'html' : 'Html document', + 'pdf' : 'Portable Document Format'} + +Notice that each key-value pair is separated by a comma, and each key and +value are separated using a colon. + +Here, we defined four entries in the dictionary extensions. The keys are +``jpg``, ``py``, ``html``, and ``pdf``. + +Simply type, + +:: + + extensions + +in the interpreter to see the content of the dictionary. Notice that in +dictionaries the order cannot be predicted and you can see that the values +are not in the order that we entered in. + +Like in lists, the elements in a dictionary can be accessed using the +index, here the index is the key. Try, + +:: + + print extensions['jpg'] + +It printed JPEG Image. And now try, + +:: + + print extensions['zip'] + +As expected it gave us an error. Obviously, our dictionary didn't have any +key 'zip', and that's what the error message says. + +Well that was about creating dictionaries, now how do we add or delete items. + +:: + + extensions['cpp'] = 'C++ code' + +Adds a new key value pair, ``cpp : C++ code`` + +We delete items using the ``del`` keyword + +:: + + del extension['pdf'] + +Let us check the content of the dictionary now, + +:: + + extensions + +So the changes have been made. Now let us try one more thing, + +:: + + extensions['cpp'] = 'C++ source code' + extensions + +As you can see, it neither added a new thing nor gave an error, but it +simply replaced the existing value with the new one. + +Now let us learn how to check if a particular key is present in the +dictionary. For that we can use ``in``, + +:: + + 'py' in extensions + 'odt' in extensions + +It will return ``True`` if the key is found in the dictionary, and +will return ``False`` if key is not present. Note that we can check +only for container-ship of keys in dictionaries and not values. + +Now let us see how to retrieve the keys and values. We can use the +method ``keys()`` for getting a list of the keys in a particular +dictionary and the method ``values()`` for getting a list of +values. Let us try them, + +:: + + extensions.keys() + +It returned the ``list`` of keys in the dictionary extensions. And now +the values, + +:: + + extensions.values() + +It returned the ``list`` of values in the dictionary. + +Now let us print the data in the dictionary. We can use ``for`` loop to +iterate. + +:: + + for each in extensions.keys(): + print each, "-->", extensions[each] + + +This brings us to the end of our discussion on dictionaries. Let us now look +at sets. + +Sets +==== + +We shall look at, + + * sets + * operations on sets + +Sets are collections of unique elements. ``set`` datastructure in Python +provides an implementation of this. + +Lets look at how to input sets. + +:: + + a_list = [1, 2, 1, 4, 5, 6, 2] + a = set(a_list) + a + +We can see that duplicates are removed and the set contains only unique +elements. + +:: + + f10 = set([1, 2, 3, 5, 8]) + p10 = set([2, 3, 5, 7]) + +* f10 is the set of fibonacci numbers from 1 to 10. +* p10 is the set of prime numbers from 1 to 10. + +Various operations that we do on sets are possible here also. + +The | (pipe) character stands for union + +:: + + f10 | p10 + +gives us the union of f10 and p10 + +The & (ampersand) character stands for intersection. + +:: + + f10 & p10 + +gives the intersection + +similarly, + +:: + + f10 - p10 + +gives all the elements that are in f10 but not in p10 + +:: + + f10 ^ p10 + +is all the elements in f10 union p10 but not in f10 intersection p10. In +mathematical terms, it gives the symmectric difference. + +Sets also support checking of subsets. + +:: + + b = set([1, 2]) + b < f10 + +gives a ``True`` since b is a proper subset of f10. + +Similarly, +:: + + f10 < f10 + +gives a ``False`` since f10 is not a proper subset. + +Where as, + +:: + + f10 <= f10 + +gives ``True`` since every set is a subset of itself. + +Sets can be iterated upon just like lists and tuples. + +:: + + for i in f10: + print i, + +prints the elements of f10. + +The length and containership check on sets is similar as in lists and tuples. + +:: + + len(f10) + +shows 5. And + +:: + + 1 in f10 + 4 in f10 + +prints ``True`` and ``False`` respectively + +The order in which elements are organised in a set is not to be relied upon. +There is no ordering of elements of a set. Sets do not support indexing and +hence slicing and striding do not make sense, either. + +Here's an example that shows the use of sets. + +Given a list of marks, marks = [20, 23, 22, 23, 20, 21, 23] list all the +duplicates + +Duplicates marks are the marks left out when we remove each element of the +list exactly one time. + +:: + + marks = [20, 23, 22, 23, 20, 21, 23] + marks_set = set(marks) + for mark in marks_set: + marks.remove(mark) + + # we are now left with only duplicates in the list marks + duplicates = set(marks) + +This brings us to the end of our discussion on sets. +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + + diff --git a/lecture_notes/index.rst b/lecture_notes/index.rst new file mode 100644 index 0000000..53edbcc --- /dev/null +++ b/lecture_notes/index.rst @@ -0,0 +1,30 @@ +.. sees-sphinx documentation master file, created by + sphinx-quickstart on Thu Jun 9 18:22:59 2011. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to sees-sphinx's documentation! +======================================= + +Contents: + +.. toctree:: + :maxdepth: 2 + + Test 1 <tests/test1> + Introduction to the course <introduction/introduction> + Using Linux Tools <ult/index.rst> + LaTeX <latex/index.rst> + Version Control <versionControl/index.rst> + Basic Python <basic_python/handOut.rst> + Advanced Python <advanced_python/handOut.rst> + Test Driven Development <tdd/tdd.rst> + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/lecture_notes/latex/handout.rst b/lecture_notes/latex/handout.rst new file mode 100644 index 0000000..2177361 --- /dev/null +++ b/lecture_notes/latex/handout.rst @@ -0,0 +1,711 @@ +Introduction +============ + +LaTeX is a typesetting program that produces excellently typeset documents. +Typesetting is placing text onto a page with all the style formatting +defined, so that content looks as intended. It is extensively used for +producing high quality scientific and mathematical documents. It may also be +used for producing other kinds of documents, ranging from simple one page +articles to complete books. LaTeX is based on the TeX typesetting language. + +LaTeX is pronounced either as "Lah-tech" or "Lay-tech". + + +Why LaTeX? +========== + +A few reasons for using LaTeX - + + * It produces documents with excellent visual quality. + * It does the typesetting for you, leaving you - the author - to focus on + writing the content. You will appreciate this, as you learn more. + * It makes writing math just as easy as writing simple text. + * It's renowned for it's stability and a virtually bug free code base. + * It is light on your resources as compared to most of the word processors + available today. + * It uses plain text files as input and can give output in a variety of + formats including PDFs and html making it platform independent. + * It is free software (free as in freedom) and gratis too. + * It is widely used and has a large user community. + + +Course Outline +============== + +In this course, we will learn enough LaTeX to be a able to produce a simple +document with text, tables, figures, math, references and bibliography. We +will also briefly see how to create presentations using LaTeX, such as the +one use for the slides of this course. + +The sample document, ``sample.pdf``, available in the course material, will +serve as a teaching/learning tool to learn LaTeX. During the course, we shall +reproduce this sample document, starting from scratch, in LaTeX + +A Look at the Sample Document +----------------------------- + +A look at the sample document gives us an idea about the various elements +present in the document, that we will be learning during this course. + +We shall be learning how to add the following elements to our LaTeX +documents. + + * Title, Author, Date + * Abstract + * Sections & Subsections + * Appendices + * References/Bibliography + * Tables + * Figures + * Math + + +LaTeX is not a Word Processor +============================= + +What do we mean by LaTeX not being a Word Processor? Suppose we wanted to +create a simple document as shown in the image below. If one used a normal +word processor, the author would have to worry about setting the font sizes +of the fonts, centering the title, date and author information, etc. + +.. image:: images/latex_not_wp.png + :alt: LaTeX is not a Word Processor + +To generate this document in LaTeX, we just tell it what we want as the +title, author's name, date etc. and what we want as the content. LaTeX takes +care of proper font size ratios and other presentation details. + +:: + + \documentclass{article} + \title{My First Document} + \author{FOSSEE} + \date{January 2011} + \begin{document} + \maketitle + Hello world! + \end{document} + +LaTeX can be considered to be a document based markup language. What we mean +by a markup language is that you mark up pieces of your text to be particular +elements of your document and then a typesetter or processor typesets your +document based on a set of rules. What do we mean by being document-based? It +means, that in LaTeX, you can change the structure of the whole document +consistently, with a few changes in the preamble of the document, with-out +having to change each element separately. + +First steps -- Typesetting a minimal document +============================================= + +Let us start with a minimal example to learn how to write a LaTeX document +and compile it to see the **typeset** output. + +To begin, type out the following code into your text editor and save it as +``draft.tex``. :: + + \documentclass{article} + \begin{document} + SciPy is open-source software for mathematics, science, and engineering. + \end{document} + +To compile your document, type the following command in your terminal:: + + $ pdflatex draft.tex + +This produces the output file ``draft.pdf`` + +Note: The ``latex`` command is often used, instead of ``pdflatex`` to get the +``dvi`` output. But, throughout this course, we shall use ``pdflatex`` to +compile our documents. + +What does it mean? +------------------ + +As we have already seen, LaTeX is a document based markup. The first line, +``\documentclass{article}``, tells that our document is an article type +document. LaTeX then, typesets the document accordingly. The documentclass +command, defines the structure and formatting of our document. + +The ``begin`` and ``end`` document commands, mark the beginning and the end +of the content of the LaTeX document. The text in between the begin and end +commands is typeset in the output document. + +A little digression +=================== + +Just like in ``bash`` and ``Python``, the commands in LaTeX are +case-sensitive. ``\Documentclass`` is therefore not a valid command. + +All the commands in LaTeX begin with a ``\``. An environment begins with a +``begin`` command and ends with an ``end`` command. In our minimal example, +``document`` is an environment. Only the text enclosed by the begin and end +commands is effected by the environment. + +So, as expected LaTeX ignores anything that is written after the +``\end{document}`` command. (The part of the file before the +``\begin{document}`` command is called the preamble, and is used to +*"configure"* the LaTeX typesetter and change various parameters for +typesetting. Details later.) + +Essentially, anything written after the ``\end{document}`` command turns out +to be a comment. But, how do we write comments with in the document. ``%`` is +the character to indicate comments. Anything written after a ``%`` symbol in +a line, is ignored. For example, we can add a comment to the minimal document +saying, this is our first document in LaTeX, by saying ``% My First LaTeX +document``. + +But what if we wanted to insert the ``%`` symbol in the document? We can do +so by escaping it with a ``\`` (backslash). ``%`` is one of the many special +characters in LaTeX. The others are, ``~ # $ ^ & _ { } \``. All of them, +except the ``\`` itself, can be inserted by escaping it with a ``\``. To +insert a ``\`` in our document, we use the command ``\textbackslash``. + +What would happen if we escape a ``\`` with a ``\``? Yes, you guessed it. A +double backslash is actually another command. It inserts a new line in the +typeset document. The ``\\`` command or ``\newline`` command is used to +insert a newline in the output document. Line breaks in the input document, +do not translate into line breaks in the output document. A single line break +in the input document, doesn't cause any change in the output. A single empty +line causes a change in paragraphs in the output. (Multiple empty lines are +equivalent to a single empty line.) Similarly, multiple spaces are treated as +a single space. + +Adding Structure +================ + +Let us now, look at giving the document some basic structure, like title, +sections, etc. + +``\documentclass`` +------------------ + +As we have already seen, the ``documentclass`` command tells LaTeX, the type +of the document that we intend to create. Some of the available LaTeX classes +are, ``article``, ``proc``, ``report``, ``book``, ``slides``, ``letter``. +Each class has a few differences in how the content of the document is +typeset. + +The ``documentclass`` command also accepts a few optional parameters. For +example:: + + \documentclass[12pt,a4paper,oneside,draft]{report} + +``12pt`` specifies the size of the main font in the document. The relative +sizes of the various fonts is maintained, when the font size is changed. If +no size is specified, ``10pt`` is assumed by default. + +``a4paper`` specifies the size of the paper to be used for the document. + +``draft`` marks the hyphenation and justification problems in the document +with a small square in the right hand margin of the document, so that they +can be easily spotted. + +Top Matter +---------- + +Let us begin with adding the Title, Author's name and the date to the +document. + +:: + + \documentclass{article} + \title{A Glimpse at Scipy} + \author{FOSSEE} + \date{June 2010} + \begin{document} + \maketitle + SciPy is open-source software for mathematics, science, and engineering. + \end{document} + +We add the title, the author and the date to the document before the +``\begin{document}`` directive. We compile the document to see if the details +appear in the document, but they donot. These details do not appear in the +document until we use the ``\maketitle`` command with the document +environment to instruct LaTeX to place the top matter information into the +document. Now the document has these details, on compiling again. + +If no date is specified, LaTeX automatically inserts the current date. + +Abstract +-------- + +Next we shall add an abstract to our document. LaTeX provides an environment, +for adding an abstract to the document. + +:: + + \documentclass{article} + + \title{A Glimpse at Scipy} + \author{FOSSEE} + \date{June 2010} + + \begin{document} + + \maketitle + + \begin{abstract} + This document shows a glimpse of the features of Scipy that will be explored during this course. + \end{abstract} + + SciPy is open-source software for mathematics, science, and engineering. + \end{document} + +The abstract environment is placed at the location where we wish it to appear +in the document. + +Sections +-------- + +Now let's look at how to add (chapters,) sections and sub-sections to our +document. Let's add the section headings and sub headings present in our +sample document to the working copy of our document. + +``\section``, ``\subsection``, ``\subsubsection`` + +On compiling, we can see that the headings of the sections and the +sub-sections appear in the document. + +You may have noticed that LaTeX automatically numbers the sections. To +prevent a section from getting numbered, an asterix is appended to the +corresponding sectioning command. + +If the document was a longer document, we could have used a report or a book +class. (Note: Books donot have the abstract environment.) Let's look at what +happens to the document, when we change it to the report class. + +The numbering strangely begins from zero, now. This is because, chapters have +an additional sectioning command called ``\chapter``. The chapter is one +level above a section and since, our document does not have a ``\chapter`` +command, the sections are numbered from 0. To change this, we add a chapter +command before the first section. We say + +:: + + \chapter{One} + +Now, observe that we now have a chapter title appearing and the numbering +starting from 1. + +Also, note that the subsubsections donot get a numbering now. This is +controlled by a variable called the secnumdepth. By default it is set to 2. +We can now, change it to 3 and get numbering for subsubsections also. + +:: + + \setcounter{secnumdepth}{3} + +What do you expect to happen if we changed the secnumdepth to 1? What if it +is 0 or -1? + + +Appendix +-------- + +Notice that our document also has an appendix. Let's add an appendix +to our document. + +:: + + \appendix + \section{Plotting using Pylab} + +Table of Contents +----------------- + +Our sample document is not long enough to warrant a table of contents, but +let us learn to add a table of contents to a LaTeX document. If you ever +tried adding a table of contents, to a document in a wordprocessor, you would +know how much of a trouble it is. In LaTeX, it is a matter of just one +command and placing the command at the location where you would want to have +the table of contents. Let's now add a table of contents to our draft. Now, +compile the document and look at the output document. It does not have the +table of contents! + +On the first compilation only the "Contents" heading appears in the document, +but the actual table does not appear. You will need to compile your document +once more, for the actual table to appear in your document. On the first run, +LaTeX has gone through your document and generated a temporary file +(``.toc``), with the entries that should go into the table of contents. These +entries are made, when you compile your document for the second time. + +Note that any section/block that has been numbered automatically appears in +the table of contents. It is possible to get un-numbered sections, for +instance a Preface or a Foreword section to appear in the Table of Contents. + +Let's change our Introduction section to be an un-numbered one and try to +make it appear in the table-of-contents. :: + + \section*{Introduction} + \addcontentsline{toc}{section}{Intro} + +We shall talk about adding and managing bibliographies, later in the course. + +Now, that we have the basic structure of the document, let's get into the +content and the details of it. + +Typesetting Text +~~~~~~~~~~~~~~~~ + +Let's begin with adding the second paragraph to the introduction section. +Let's place the text of the second para, after the first line, that we +already have. Now, compile the document. + +As already discussed, we need to an insert an empty line, to insert a new +paragraph in LaTeX. Also, notice that the new paragraph is indented. + +Quotation Marks +--------------- + +Look at the quotation marks around the text, Sigh Pie. They are not formatted +properly. To place quotation marks in LaTeX, you should use ````` character +for the left quote & ``'`` character for the right quote. For double quotes, +they should be used twice. + +Fonts +----- + +The names of the software tools, Scilab, Matlab, etc. appear in italics or +emphasized as it is called in LaTeX. To emphasize text, the ``\emph`` command +is used. + +Let's also add the contents of the subsection "Sub-packages of Scipy". We +shall add the table as plain text, until we learn how to edit tables. + +Let's try and form a tabular structure by separating the left and right +columns using spaces. On compiling we find that LaTeX doesn't add multiple +spaces between words. Just like multiple empty lines, multiple spaces are +considered as a single space. + +Also, we notice that ``LaTeX`` starts a new paragraph at the beginning of the +table. To avoid this, we use the ``flushleft`` environment. + +The names of the sub-packages appear in a fixed width font in the sample +document provided to us. The headings of the columns appear in bold-face. +Let's make changes to this effect. + +``\textbf`` is used to change text to bold face and ``\texttt`` is used to +change text to fixed width font. + +We could also change the separating - (hyphen) to an em-dash (or en-dash) -- +is em-dash and --- is an em-dash, to improve the appearance of the document. + +Lists +===== + +The section on Use of Scipy in this course, contains lists. Let's now add +lists to our document. The ``enumerate`` environment adds numbered lists to +our document and the ``itemize`` environment adds un-numbered lists. +``\item`` command adds a new entry to a list. Note, that LaTeX can easily +handle nested lists. In fact most environments can be embedded within other +environments, without any problems. + +LaTeX also has a description list, which shall be an exercise, for you. + + +Footnotes, Labels and References +================================ + +Let's now add the footnote to pylab. LaTeX provides a footnote command to add +a footnote. + +We added the footnote with Appendix A, as plain text. But, in case we added +another Appendix before the section on using ``pylab``, the footnote will +have to be edited. To avoid this, LaTeX provides a handy system of labels and +referencing. + +We first add a label to the section that we want to refer in this +footnote. Then, we change the footnote, and add the reference to this +label instead of the character A. If you look at the output after +compiling the document once, you will see that the footnote has +question marks instead of the section number. You will have to +compile once again, for the section number to appear in the footnote. + + +Including code +============== + +In the footnote above, and in the table for the sub-packages list, we +used the ``\texttt`` command to get a fixed width font. But we could +instead use an environment provided by LaTeX to include pre-formatted +text or code. LaTeX by default provides the verbatim environment to +include pre-formatted text. You can try that out during the lab +session. We shall look at using the listings package, specifically +meant for including code in our document. + +First of all you need to tell LaTeX, that you want to use the listings +package in your document. We add the directive +``\usepackage{listings}`` to the preamble of our document. + +Then we set the language of the code that we are going to embed into +our document. For this we use the lstset command. :: + + \lstset{language=Python, + showstringspaces=false,} + +The listings package allows you to use color and do a lot of things +with your embedded code, but all that during a lab exercise. + +Now, to put a line of code, inline and not as a separate block, we use +the ``\lstinline`` command. We change the name pylab in the footnote +to use lstinline instead of the texttt. To embed a block of code, we +use the lstlisting environment (``\begin{lstlisting}`` and +``\end{lstlisting}``). For example, let's add the code to the Appendix +of our document. + +Figures, Tables and Floats +========================== + +Let's now add the figure, to the appendix. + +To include graphics in a LaTeX document, we need to use the graphicx +package. Add the ``\usepackage{graphicx}`` directive to the preamble +of the document. + +To add the graphic, use the ``includegraphics`` command. The relative +path of the image that we wish to include is passed as an argument to +includegraphics. It takes an optional argument of scaling the +image. We use a scale of 0.4 to scale our image. + +It takes other optional arguments. + + ``width=x``, ``height=x`` + If only the height or width is specified, + the image is scaled, maintaining the aspect ratio. + + ``keepaspectratio`` + This parameter can either be set to true or false. When set to + true, the image is scaled according to both width and height, + without changing the aspect ratio, so that it does not exceed both + the width and the height dimensions. + + ``angle=x`` + This option can be used to rotate the image by ``x`` degrees, + counter-clockwise. + +Figures (and tables) are treated specially because, they cannot be +broken across pages. They are "floated" across to the next page, if +they donot fit on the current page, filling the current page with +text. + +To make our graphic into a float, we should enlose it within a figure +environment. For a table, the table environment should be used. We now +move our graphic into a figure environment. The figure environment +takes an additional parameter for the location of the +float. ``\begin{figure}[hbtp!]``. The specifiers ``htbp`` are +permissions to place the float at various locations. ``t`` for top of +page, ``b`` for bottom of page, ``p`` for a separate page for floats +and ``h`` for here, as in the same place where the command appears in +the source. ``!`` mark overrides a few of LaTeX's internal parameters +for good position of floats. + +The figure environment also, allows us to add a caption to the graphic +using the ``\caption`` command. + +To place the graphic in the center aligned in the page, we use the +center environment. + +To label a figure, we just add a label with in the figure +environment. Note, that the label to a figure should be added after +the caption command. Also, note that tables are auto-numbered. + +Let us finish the appendix, by adding the content present at the +beginning of the appendix. The bibliographic citations will be dealt +with later. + +Tables +------ + +Now, let us look at the other kind of floats - Tables. We shall +convert the list of sub-packages in the sub-packages section to a +table. + +To begin a table, we use the tabular environment. And to make this a +float, it is enclosed in the table environment. The table environment +also allows us to add captions to the table and Tables are also auto +numbered. + +The tabular environment takes as arguments the columns and the +formatting of each column. The possible arguments to the tabular +environment are + ++---------------+------------------------------------+ +| ``l`` | left justified column content | ++---------------+------------------------------------+ +| ``r`` | right justified column content | ++---------------+------------------------------------+ +| ``c`` | centered column content | ++---------------+------------------------------------+ +| ``|`` | produces a vertical line. | ++---------------+------------------------------------+ + +It also takes an optional parameter that specifies the position of the +table; ``t`` for top, ``b`` for bottom, or ``c`` for center. + +Each column of a table is separated by an ``&`` symbol and each row is +separated by a new line. The ``\hline`` command allows you to draw +horizontal lines between two rows of the table. But it does not allow +you do draw partial lines. ``\cline{a-b}`` draws a horizontal line +from column ``a`` to column ``b``. + +We also add a label to the table and refer to it in the first line of +the section. + +You could also add a listoftables or listoffigures to the document, +similar to the way we added table of contents. + +Typesetting Math +================ + +Now we shall move to typesetting the Math in the sample document given +to us. We shall start with the Matrices subsection. + +In general, it is advised to use the AMS-LaTeX bundle to typeset +mathematics in LaTeX. AMS-LaTeX is a collection of packages and +classes for mathematical typesetting. + +We load ``amsmath`` by issuing the ``\usepackage{amsmath}`` in the +preamble. Through out this section, it is assumed that the ``amsmath`` +package has been loaded. + +Let's now typeset the matrix A. + +To typeset math, we just have to enclose it within ``\(`` and ``\)`` +or a pair of ``$`` signs. + +To typeset the matrix A, we use the ``bmatrix`` environment. It works +similar to a tabular environment - ``&`` is used to demarcate columns +and ``\\`` is used to add a new row. ``bmatrix`` environment gives the +``[`` ``]`` as delimiters. There are 5 other matrix environments +giving matrices with other delimiters - ``matrix`` (none), ``pmatrix`` +``(``, ``Bmatrix`` ``{``, ``vmatrix`` ``|`` and ``Vmatrix`` ``||``. + +To write the name of the matrix A, a bold-faced A is used. This is +obtained by using the ``\mathbf`` command. + +This subsection doesn't have much more math. The next section on +inverse doesn't have anything new except for writing inverse of A. + +To typeset superscripts in LaTeX, the ``^`` character is used. The +carat operator just acts on the next character. To have multiple +characters as superscript they must be enclosed in ``{ }``. Similarly +for typesetting text as subscripts the ``_`` character is used. + +To typeset the summation symbol, use the command ``\sum.`` The upper +and lower limits are specified using the ``^`` and ``_`` +characters. Similarly, the integral symbol is obtained using the +``\int`` command. + +Next, let us type in the equation present in the section on +Determinants. Note that it is different from all the math we've typed +until now, since it is not inline and is "displayed", in the LaTeX +lingo. LaTeX has a number of environments for displaying equations, +with minor subtle differences. In general use ``\[`` ``\]`` to typeset +displayed equations without numbering them. ``\begin{equation*}`` is +equivalent to it. To obtain numbered equations use +``\begin{equation}``. + +Next we wish to typeset a group of equations. The equation environment +does not accept ``\\`` to get a new line. For multiple equations +amsmath has a handful of environments with subtle differences. We +shall use the ``eqnarray`` environment. ``eqnarray*`` environment +gives unnumbered equations, as expected. The ``eqnarray`` environment +works similar to a table environment. The parts of the equation that +need to be aligned are indicated using an ``&`` symbol. The +``newline`` command is used to enter a every new equation after the +first one. We now typeset the equations in the section on linear +equations using the ``eqnarray`` environment. (The equations in the +determinants section use ``eqnarray*``) + +We next typeset the math in the section on polynomials. To typeset +fractions use the ``\frac`` command. To typeset surds, we use the +``\sqrt`` command with the optional paramter of ``[n]``. + +Inserting Greek letters into LaTeX is simple. ``\alpha``, ``\beta``, +``\gamma``, ... on for small letters and ``\Alpha``, ``\Beta``, +``\Gamma``, ... for capital. + +Also, math environments do not give extra spaces using the space or +tab characters. The following commands are available to specify the +spacing required. + ++---------+--------------------+---------+ +| Abbrev. | Spelled out | Example | ++---------+--------------------+---------+ +| ``\,`` | ``\thinspace`` | | ++---------+--------------------+---------+ +| ``\:`` | ``\medspace`` | | ++---------+--------------------+---------+ +| ``\;`` | ``\thickspace`` | | ++---------+--------------------+---------+ +| | ``\quad`` | | ++---------+--------------------+---------+ +| | ``\qquad`` | | ++---------+--------------------+---------+ +| ``\!`` | ``\negthinspace`` | | ++---------+--------------------+---------+ +| | ``\negmedspace`` | | ++---------+--------------------+---------+ +| | ``\negthickspace`` | | ++---------+--------------------+---------+ + +Bibliography +============ + +Let's now look at how to write bibliography and cite references. + +Writing bibliographies in LaTeX using the ``thebibliography`` +environment is pretty easy. You simply have to list down all the +bibliography items within the bibliography environment. + +Each entry of the bibliography begins with the command +``\bibitem[label]{name}``. The name is used to cite the bibliography +item within the document using ``\cite{name}``. The label option +replaces the numbers from the auto enumeration with the labels given. + +The ``9`` passed as an argument to ``thebibliography`` command +indicates the maximum width of the label that the references will +have. In our sample document, we have less than 10 items in the +Bibliography and therefore we use 9. + +Presentations with Beamer +========================= + +Using beamer for you presentations is a good idea, since you can use +the LaTeX that you have used for the report/document for the +presentation as well. + +To write a ``beamer`` presentation, it is recommended that we use one +of the templates that beamer provides. We shall use the +``speaker_introduction`` template to get started with beamer. + +As you can see, the document begins with the ``documentclass`` being +set to beamer. + +``\usetheme`` command sets the theme to be used in the presentation. + +``\usecolortheme`` command sets the color theme of the presentation. + +Notice that each slide is enclosed within ``\begin{frame}`` and +``\end{frame}`` commands. The ``\begin{frame}`` command can be passed +the Title and Subtitle of the slide as parameters. + +The title page of the presentation can be set like any other LaTeX +document. + +To do overlays, use the ``\pause`` command. It does sequential +overlays. Non sequential overlays can also be done. (Lab exercise.) + +If you have fragile environments like ``verbatim`` or ``lstlisting``, +you need to give the frame an optional parameter ``[fragile]``. + +To achieve more with beamer, it is highly recommended that you look at +the ``beameruserguide``. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: diff --git a/lecture_notes/latex/images/latex_not_wp.png b/lecture_notes/latex/images/latex_not_wp.png Binary files differnew file mode 100644 index 0000000..1836d17 --- /dev/null +++ b/lecture_notes/latex/images/latex_not_wp.png diff --git a/lecture_notes/latex/index.rst b/lecture_notes/latex/index.rst new file mode 100644 index 0000000..cd0c36e --- /dev/null +++ b/lecture_notes/latex/index.rst @@ -0,0 +1,6 @@ +====== + LaTeX +====== + +.. include :: handout.rst +.. include :: lab-workbook.rst diff --git a/lecture_notes/latex/lab_workbook.rst b/lecture_notes/latex/lab_workbook.rst new file mode 100644 index 0000000..62eb78f --- /dev/null +++ b/lecture_notes/latex/lab_workbook.rst @@ -0,0 +1,112 @@ +Exercises +========= + +Lab-1 +----- + +#. Compile and produce a pdf output of ``example1.tex``. + +#. Modify ``example1.tex`` replacing ``LaTeX`` with {\\LaTeX}. + +#. Add a title, author and date to the document. + +#. What happens if {\\date} is replaced by {\\date{IIT, Bombay}} ? + +#. Debug and compile examples 2, 3, 4, 5 + +#. Provide a document (pdf and source) with a TOC, but has been compiled + only once. Exercise for Debugging. + +#. What happens when you add the following {} code to the document from + the previous question? + + :: + + \renewcommand{\contentsname}{What is Here?} + +#. Experiment with setting the secnumdepth counter to 1, 0, -1. + +#. Debug and compile example 6. + +#. Experiment with the options of {\\documentclass}. + + - 10pt, 11pt, 12pt sets the size of the text of the document. + + - onecolumn, twocolumn + + - draft — makes {} highlight problems in typesetting to be looked at + by a human. + +Lab-2 +----- + +#. {\\newpage} command adds a page break. Add some page breaks to + example 6 and see how the command works. + +#. Try out the commands {\\pagestyle} and {\\thispagestyle} with the + following parameters and look at the outputs obtained. + + - ``empty``, + + - ``plain``, + + - ``heading`` + +#. Add the following description list describing the options to + {\\includegraphics} command to a document and look at the output. + + :: + + \begin{description} + \item[{\texttt{width=x}, \texttt{height=x}}] + If only the height or width is specified, the image is scaled, maintaining the aspect ratio. + + \item[{\texttt{keepaspectratio}}] + This parameter can either be set to true or false. When set to true, the image is scaled according to both width and height, without changing the aspect ratio, so that it does not exceed both the width and the height dimensions. + + \item[{\texttt{angle=x}}] + This option can be used to rotate the image by \texttt{x} degrees, counter-clockwise. + + \end{description} + +#. {\\ldots} is used to get ellipsis in {} documents. + +#. Read the manual of listings package and learn how to include a set of + lines from a file into a {} document. Include a few lines from your + previous lab exercises of ULT. + +#. To change the line spacing of your document {\\usepackage{setspace}} + and then specify the line spacing of your document, using + {\\doublespace}, {\\onehalfspace}, etc. + +#. Debug and compile examples 9, 10 + +Lab-3 +----- + +#. Debug and compile example 7. + +#. BibTeX is another way of handling bibliography. Look at bibtex.rst + and change draft.tex to use BibTeX. + +#. As you would’ve already observed, {} compilation produces a lot of + other files along with the pdf output. + + - .log — gives a log of what happened during last compilation. + + - .toc — stores section headers. Edit this file and observe changes + in this document to see how the compilation of {} works and why + two compilations are required for table of contents to work. + + - .aux — used to share information between consecutive compiler + runs. + +#. Prepare a presentation in beamer with solutions to any 10 problems + from the Lab workbook. + +#. Debug and compile example 8. + +#. Finish the incomplete parts of the draft to obtain the complete + output of the sample document that we started out to prepare. + + diff --git a/lecture_notes/latex/module_plan.rst b/lecture_notes/latex/module_plan.rst new file mode 100644 index 0000000..d30539a --- /dev/null +++ b/lecture_notes/latex/module_plan.rst @@ -0,0 +1,74 @@ +LaTeX +===== + +Module Objectives +----------------- + +After completing this module, a participant will be successfully able to: + +- Produce professional documents in LaTeX. RBT Ap +- Typeset Mathematical equations. RBT Ap +- Include figures, tables and code samples. RBT Ap +- Add References and write BibTeX files. RBT Ap + +Suggested Reading +----------------- + +1. *LaTeX Wikibook* + +2. *The Not So Short Introduction to LaTeX2e* by Tobias Oetikar et. al. + + +Session Level Split-up +---------------------- + ++----------------------------------+--------+ +| Session Details | Time | ++----------------------------------+--------+ +| Introduction | 20 min | +| - TeX & LaTeX | | +| - Why LaTeX | | +| - LaTeX as a markup | | +| - Typesetting a minimal document | | +| - commands, environments | | +| - comments, special characters | | +| - Spacing | | +| | | +| Adding Structure | 25 min | +| - documentclass, top matter | | +| - abstract | | +| - sections | | +| - appendix | | +| - ToC | | +| | | +| Typesetting Text | 20 min | +| - quotation marks | | +| - emphasis | | +| - lists | | +| - footnotes | | +| - labels and references | | +| - verbatim, lstlisting | | ++----------------------------------+--------+ +| Figures, Tables & Floats | 20 min | +| - includegraphics | | +| - floats | | +| - captions & references | | +| - tabular | | +| - list of tables, figures | | +| | | +| Typesetting Math | 25 min | +| - amsmath | | +| - matrices | | +| - sub-scripts, superscripts | | +| - summation, integration | | +| - displayed math | | +| - groups of equations | | +| - fractions, surds | | +| - greek letters, spacing | | +| | | +| Bibliography | 5 min | +| | | +| Presentations - Beamer | 10 min | ++----------------------------------+--------+ + + diff --git a/lecture_notes/tdd/generate_testcases.py b/lecture_notes/tdd/generate_testcases.py new file mode 100644 index 0000000..17b48a7 --- /dev/null +++ b/lecture_notes/tdd/generate_testcases.py @@ -0,0 +1,36 @@ +import random + +def gcd(a, b): + while b != 0: + a, b = b, a % b + return a + +a = random.sample(xrange(100), 10) +b = random.sample(xrange(1000), 10) +c = random.sample(xrange(10000), 10) +c = random.sample(xrange(10000), 10) +d = random.sample(xrange(100000), 10) +e = random.sample(xrange(1000000), 10) +f = a + b + c + d + e +f.sort() +a = random.sample(xrange(100), 10) +b = random.sample(xrange(1000), 10) +c = random.sample(xrange(10000), 10) +d = random.sample(xrange(100000), 10) +e = random.sample(xrange(1000000), 10) +g = a + b + c + d + e + +testcases = [] +for item in f: + a = f[random.randrange(0, len(f))] + b = g[random.randrange(0, len(g))] + gc = gcd(a, b) + testcases.append([a, b, gc]) + +sortedcases = sorted(testcases, key=lambda case: case[0]) + +fil = open('/home/madhu/Desktop/gcdtest.dat', 'w') +for case in sortedcases: + fil.write('%d, %d, %d\n' % (case[0], case[1], case[2])) + +fil.close() diff --git a/lecture_notes/tdd/lab_workbook.rst b/lecture_notes/tdd/lab_workbook.rst new file mode 100644 index 0000000..fa5afa4 --- /dev/null +++ b/lecture_notes/tdd/lab_workbook.rst @@ -0,0 +1,146 @@ +====================================== +Lab Workbook - Test Driven Development +====================================== + +The notation that follows every question denotes the level on the +Revised Bloom's Taxonomy. + +Lab - 1 +======= + + 1. Write a stub function for calculating the LCM of two numbers. + - U-level + 2. Write the tests for the LCM function, place the tests in if + __name__ == '__main__': part of the Python file. Demonstrate that + the tests fail. - U-level + 3. Implement the code for the LCM function, using the gcd function + provided in the examples in the chapter. Demonstrate the tests + pass. (For the algorithm refer to Wikipedia - [0]) - Ap-level + 4. Alternatively, build a set of test cases, preferably a large + number of cases, place it in a text file and use these test cases + to test your LCM function. Demonstrate that tests still continue + to pass. - U-level + +[0] - http://en.wikipedia.org/wiki/Least_common_multiple#Reduction_by_the_greatest_common_divisor + +Lab - 2 +======= + + 1. Write the stub function, followed by the tests(demonstrating the + failed tests), in turn followed by the code(demonstrating the + passing tests) to calculate the number of days between two + dates. Name your function num_of_days(). The function should take + two arguments, both being tuples. Each tuple represents the date + in the format of (dd, mm, yyyy) where dd, mm and yyyy are + integers. - Ap-level + + 2. Rewrite the num_of_days() function to take the start date as an + optional argument. If the start date is not specified calculate + the number of days between the only specified date since Unix + epoch. Prior to manipulating the code to do this, make sure you + change the tests, make them fail and then refactor the code. + - Ap-level + + +Lab -3 +====== + + 1. Move the tests that were written to GCD function in the examples + of this chapter to a separate function called test_gcd(). Do the + same for LCM function and num_of_days() function. Make sure when + the respective Python files are executed as stand alone scripts + these tests executed. - U-level + 2. Put all these files in a single directory called utils and run + the nosetests command. Make a report of the results. - U-level + 3. Write doctests to each of the above functions. Demonstrate and + report the results as executed by running the doctests using + doctest.testmod() function and using nosetests command. -Ap-level + +Lab - 4 +======= + + 1. Consider the following use case: We are given a large list of + items called *data* where each item is a again a list with three + values: username, which is a string; status of the user which + can be one of the following three strings 'new', 'valid' or + 'invalid'; and the last login time which is a datetime Python + object. Write a function called **query** that takes a filter + dictionary as a parameter and returns the result of the items in + the *data* list. They keys of the dictionary can be 'user', + 'status' and 'logtime' and their corresponding values can be any + of the valid values for the corresponding key. Example filter + dictionary:: + + filter = { + 'user': 'john' + 'status': 'new' + } + + Place your function in a file called query.py. Before writing the + actual function, follow the test driven development + approach. First write a stub, fail the tests and then write the + code and make sure the tests pass. Specifically use unittest + framework to test this function. Place your tests in a file + called test_query.py + + A developer wrote a small utility function in a file named + user_utils.py which uses your **query** function which looks as + follows:: + + def login_util(user=None): + """Takes a user name and returns his last login time if the + user is a valid user, else return None. If the user is + 'host' it returns the last login time of all the users. + """ + + filter_dict = { + 'user': user + 'status': 'active' + } + + if user == 'host': + filter_dict['status'] + ['new', 'invalid'] + + return query(filter_dict) + + Unfortunately the developer did not provide us with the test + cases. We wrote the following test cases for you to only discover + that the function miserably fails. + + The tests were placed in a file called test_user_utils.py and we + have used the unittest framework:: + + import query + import user_utils + import unittest + + class TestUserUtils(unittest.TestCase): + + def setUp(self): + """Boiler plate method to provide common data to all + the test methods. + """ + self.test_names = ['Alex', 'Guido', 'Thomas', 'host', + 'Tom', 'James'] + self.data_len = len(query.data) + + def test_login_utils(self): + """Tests for the login_utils function. + """ + + for name in self.test_names: + if name == 'host': + assertEqual(len(user_utils.login_utils(name)), self.data_len) + else: + assertLess(len(user_utils.login_utils(name)), self.data_len) + + def tearDown(self): + """Boiler plate method to clean up all the data created + for tests. + """ + + del self.test_names + del self.data_len + + Fix the bug, run the tests to make sure the function passes the + tests and if possible refactor the code with a better approach. - An-level diff --git a/lecture_notes/tdd/math_utils/gcd.py b/lecture_notes/tdd/math_utils/gcd.py new file mode 100644 index 0000000..7204ac0 --- /dev/null +++ b/lecture_notes/tdd/math_utils/gcd.py @@ -0,0 +1,22 @@ +def gcd(a, b): + """Returns the Greatest Common Divisor of the two integers + passed as arguments. + + Args: + a: an integer + b: another integer + + Returns: Greatest Common Divisor of a and b + + >>> gcd(48, 64) + 16 + >>> gcd(44, 19) + 1 + """ + if b == 0: + return b + return gcd(b, a%b) + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/lecture_notes/tdd/math_utils/gcd_testcases.dat b/lecture_notes/tdd/math_utils/gcd_testcases.dat new file mode 100644 index 0000000..3829b12 --- /dev/null +++ b/lecture_notes/tdd/math_utils/gcd_testcases.dat @@ -0,0 +1,50 @@ +6, 22, 2 +6, 48744, 6 +14, 143295, 1 +22, 751, 1 +35, 79, 1 +35, 96, 1 +52, 12, 4 +73, 79, 1 +73, 184790, 1 +86, 11, 1 +93, 8, 1 +93, 798, 3 +113, 42785, 1 +209, 2135, 1 +395, 8989, 1 +587, 331, 1 +643, 751, 1 +721, 242525, 1 +733, 5622, 1 +854, 42785, 1 +1695, 57, 3 +1695, 798, 3 +3429, 177203, 1 +4603, 12, 1 +4603, 48744, 1 +6139, 57, 1 +6139, 204, 1 +6660, 96, 12 +6660, 410400, 180 +6703, 410400, 1 +8964, 22, 2 +9673, 751, 1 +9673, 7909, 1 +9673, 3335, 1 +16028, 891, 1 +44231, 378, 1 +49020, 751, 1 +57908, 184790, 2 +65482, 548045, 1 +79715, 8, 1 +79715, 891, 1 +79715, 66371, 1 +321807, 891, 3 +366607, 97, 1 +402212, 5595, 1 +448426, 66371, 1 +575271, 4617, 9 +575271, 402152, 1 +680256, 48744, 72 +779565, 184790, 5 diff --git a/lecture_notes/tdd/math_utils/test_gcd.py b/lecture_notes/tdd/math_utils/test_gcd.py new file mode 100644 index 0000000..c81c72b --- /dev/null +++ b/lecture_notes/tdd/math_utils/test_gcd.py @@ -0,0 +1,29 @@ +import gcd +import unittest + +class TestGcdFunction(unittest.TestCase): + + def setUp(self): + self.test_file = open('gcd_testcases.dat') + self.test_cases = [] + for line in self.test_file: + values = line.split(', ') + a = int(values[0]) + b = int(values[1]) + g = int(values[2]) + + self.test_cases.append([a, b, g]) + + def test_gcd(self): + for case in self.test_cases: + a = case[0] + b = case[1] + g = case[2] + self.assertEqual(gcd.gcd(a, b), g) + + def tearDown(self): + self.test_file.close() + del self.test_cases + +if __name__ == '__main__': + unittest.main() diff --git a/lecture_notes/tdd/tdd.rst b/lecture_notes/tdd/tdd.rst new file mode 100644 index 0000000..6347c47 --- /dev/null +++ b/lecture_notes/tdd/tdd.rst @@ -0,0 +1,656 @@ +======================= +Test Driven Development +======================= + +What is TDD? +============ + +Objectives +---------- +At the end of this section, you will be able to: + +1. Write your code using the TDD paradigm. +#. Use doctests to test your Python code. +#. Use unittests to test your Python code. +#. Use the nose module to test your code. + + +Test Driven Development (TDD), as the name suggests, is a style or method +of software development based on the idea of writing code, after writing +tests for them. As the tests are written for code, that doesn't even exist +yet, it is bound to fail. Actual code is later written, to pass the test +and later on refactored. + +The basic steps of TDD are roughly as follows - + +1. Decide upon the feature to implement and the methodology of testing it. +#. Write the tests for the feature decided upon. +#. Just write enough code, so that the test can be run, but it fails. +#. Improve the code, to just pass the test and at the same time passing all + previous tests. +#. Run the tests to see, that all of them run successfully. +#. Refactor the code we've just written -- optimize the algorithm, remove + duplication, add documentation, etc. +#. Run the tests again, to see that all the tests still pass. +#. Go back to 1. + +First "Test" +============ + +Now, that we have an overview of TDD, let's get down to writing our first +test. Let us consider a very simple program which returns the Greatest +Common Divisor (GCD) of two numbers. + +Before being able to write our test, we need to have a clear idea of the +code units our program will contain, so that we can test each of them. +Let's first define the code units that our GCD program is going to have. + +Our program is going to contain only one function called ``gcd``, which +will take in two arguments, and return a single value, which is the GCD of +the two arguments. So if we want to find out GCD of 44, 23, we call the +function, with the arguments 44 and 23. + +:: + + c = gcd(44, 23) + +c will contain the GCD of the two numbers. + +We have defined the code units in our program. So, we can go ahead and +write tests for it. + +When adopting the TDD methodology, it is important to have a clear set of +results defined for our code units i.e., for every given set of inputs as +that we wish use as a test case, we must have, before hand, the exact +outputs that are expected for those input test cases. We must not be +running around looking for outputs for our test cases after we have the +code ready, or even while we are writing the tests. + +Let one of our test cases be 48 and 64 as ``a`` and ``b``, respectively. +For this test case we know that the expected output, the GCD, is 16. Let +our second test case be 44 and 19 as ``a`` and ``b``, respectively. We know +that their GCD is 1, and that is the expected output. + +But before writing one, we should What does a test look like? What does it +do? Let's answer this question first. + +Tests are just a series of assertions which are either True or False +depending on the expected behaviour of the code and the actual behaviour. +Tests for out GCD function could be written as follows. + +:: + + tc1 = gcd(48, 64) + if tc1 != 16: + print "Failed for a=48, b=64. Expected 16. Obtained %d instead." % tc1 + exit(1) + + tc2 = gcd(44, 19) + if tc2 != 1: + print "Failed for a=44, b=19. Expected 1. Obtained %d instead." % tc2 + exit(1) + + print "All tests passed!" + +The next step is to run the tests we have written, but if we run the tests +now, the tests wouldn't even run. Why? We don't even have the function +``gcd`` defined, for it to be called by the tests. The test code doesn't +even run! What is the way out? We shall first write a very minimal +definition (or a stub) of the function ``gcd``, so that it can be called by +the tests. + +A minimal definition for the ``gcd`` function would look like this + +:: + + def gcd(a, b): + pass + +As you can see, the stub for ``gcd`` function does nothing, other than +define the required function which takes the two arguments a and b. No +action is done upon the arguments, passed to the function, yet. The +function definition is empty and just contains the ``pass`` statement. + +Let us put all these in a file and call this file ``gcd.py`` + +:: + + def gcd(a, b): + pass + + if __name__ == '__main__': + tc1 = gcd(48, 64) + if tc1 != 16: + print "Failed for a=48 and b=64. Expected 16. Obtained %d instead." % tc1 + exit(1) + + tc2 = gcd(44, 19) + if tc2 != 1: + print "Failed for a=44 and b=19. Expected 1. Obtained %d instead." % tc2 + exit(1) + + print "All tests passed!" + +Recall that, the condition ``__name__ == '__main__'`` becomes true, only +when the python script is ran directly as a stand-alone script. So any code +within this ``if`` block is executed only when the script is run as a +stand-alone script and doesn't run when it is used as a module and +imported. + +Let us run our code as a stand-alone script. + +:: + + $ python gcd.py + Traceback (most recent call last): + File "gcd.py", line 7, in <module> print "Failed for a=48 and b=64. Expected 16. Obtained %d instead." % tc1 + TypeError: %d format: a number is required, not NoneType + +We now have our tests, the code unit stub, and a failing test. The next +step is to write code, so that the test just passes. + +Let's us the algorithm given by a greek mathematician, 2300 years ago, the +Euclidean algorithm, to compute the GCD of two numbers. + +**Note**: If you are unaware of Euclidean algorithm to compute the gcd of +two numbers please refer to it on wikipedia. It has a very detailed +explanation of the algorithm and its proof of validity among other things. + +The ``gcd`` stub function can be modified to the following function, + +:: + + def gcd(a, b): + if a == 0: + return b + while b != 0: + if a > b: + a = a - b + else: + b = b - a + return a + +Now let us run our script which already has the tests written in it and see +what happens + +:: + + $ python gcd.py + All tests passed! + +Success! We managed to write code, that passes all the tests. The code we +wrote was simplistic, actually. If you take a closer look at the code you +will soon realize that the chain of subtraction operations can be replaced +by a modulo operation i.e. taking remainders of the division between the +two numbers since they are equivalent operations. The modulo operation is +far better, since it combines a lot of subtractions into one operation and +the reduction is much faster. Take a few examples, and convince yourself +that using the modulo operation is indeed faster than the subtraction +method. + +:: + + def gcd1(a, b): + while b != 0 and a != 0: + if a > b: + a = a%b + else: + b = b%a + if a == 0: + return b + else: + return a + +But we know that the modulo of ``a%b`` is always less than b. So, if the +condition ``a>b`` is True in this iteration, it will definitely be False in +the next iteration. Also note that , and in the case when ``a < b``, +``a%b`` is equal to ``a``. So, we could, essentially, get rid of the +``if-else`` block and combine a swapping operation along with the modulo +operation. + +:: + + def gcd(a, b): + while b != 0: + a, b = b, a % b + return a + +Let's run our tests again, and check that all the tests are passed, again. + +We could make one final +improvement to our ``gcd`` function, which is strictly not necessary in +terms of efficiency, but is definitely more readable and easy to +understand. We could make our function a recursive function, as shown below + +:: + + def gcd(a, b): + if b == 0: + return a + return gcd(b, a%b) + +Much shorter and sweeter! We again run all the tests, and check that they +are passed. It indeed does pass all the tests! + +But there is still one small problem. There is no way, for the users of +this function, to determine how to use it, how many arguments it takes and +what it returns, among other things. This is a handicap for the people +reading your code, as well. This is well written function, with no +documentation whatsoever. + +Let's add a docstring as shown, + +:: + + def gcd(a, b): + """Returns the Greatest Common Divisor of the two integers + passed as arguments. + + Args: + a: an integer + b: another integer + + Returns: Greatest Common Divisor of a and b + """ + if b == 0: + return a + return gcd(b, a%b) + +Now we have refactored our code enough to make it well written piece +of code. We have now successfully completed writing our first test, writing +the relevant code, ensuring that the tests are passed and refactoring the +code, until we are happy with the way it works and looks. + +Let's now build on what we have learnt so far and learn more about writing +tests and improve our methodology of writing tests and simplify the process +of writing them. + +Persistent Test Cases +--------------------- + +As already stated, tests should be predetermined and you should have your +test cases and their outputs ready, even before you write the first line of +code. This test data is repeatedly used in the process of writing code. So, +it makes sense to have the test data to be stored in some persistent format +like a database, a text file, a file of specific format like XML, etc. + +Let us modify the test code for the GCD function and save our test data in +a text file. Let us decide upon the following format for the test data. + + 1. The file has multiple lines of test data. + 2. Each line in this file corresponds to a single test case. + 3. Each line consists of three comma separated values -- + + i. First two coloumns are the integers for which the GCD has to + be computed + ii. Third coloumn is the expected GCD to the preceding two + numbers. + +Now, how do we modify our tests to use this test data? We read the file +line by line and parse it to obtain the required numbers whose GCD we wish +to calculate, and the expected output. We can now call the ``gcd`` function +with the correct arguments and verify the output with the expected output. + +Let us call our data file ``gcd_testcases.dat`` + +:: + + if __name__ == '__main__': + for line in open('gcd_testcases.dat'): + values = line.split(', ') + a = int(values[0]) + b = int(values[1]) + g = int(values[2]) + + tc = gcd(a, b) + if tc != g: + print "Failed for a=%d and b=%d. Expected %d. Obtained %d instead." % (a, b, g, tc) + exit(1) + + print "All tests passed!" + +When we execute the gcd.py script again we will notice that the code passes +all the tests. + +Now, we have learnt how to write simple test cases and develop code based +on these test cases. We shall now move on to learn to use some testing +frameworks available for Python, which make some of the task easier. + +Python Testing Frameworks +========================= + +Python provides two ways to test the code we have written. One of them is +the unittest framework and the the other is the doctest module. To start +with, let us discuss the doctest module. + +doctest +~~~~~~~ + +As we have already discussed, a well written piece of code must always be +accompanied by documentation. We document functions or modules using +docstrings. In addition to writing a generic description of the function or +the module, we can also add examples of using these functions in the +interactive interpreter to the docstrings. + +Using the ``doctest`` module, we can pick up all such interactive session +examples, execute them, and determine if the documented piece of code runs, +as it was documented. + +The example below shows how to write ``doctests`` for our ``gcd`` function. + +:: + + def gcd(a, b): + """Returns the Greatest Common Divisor of the two integers + passed as arguments. + + Args: + a: an integer + b: another integer + + Returns: Greatest Common Divisor of a and b + + >>> gcd(48, 64) + 16 + >>> gcd(44, 19) + 1 + """ + if b == 0: + return a + return gcd(b, a%b) + +That is all there is, to writing a ``doctest`` in Python. Now how do we use +the ``doctest`` module to execute these tests. That too, is fairly straight +forward. All we need to do is tell the doctest module to execute, using the +``doctest.testmod`` function. + +Let us place this piece of code at the same place where we placed our tests +earlier. So putting all these together we have our ``gcd.py`` module which +looks as follows + +:: + + def gcd(a, b): + """Returns the Greatest Common Divisor of the two integers + passed as arguments. + + Args: + a: an integer + b: another integer + + Returns: Greatest Common Divisor of a and b + + >>> gcd(48, 64) + 16 + >>> gcd(44, 19) + 1 + """ + if b == 0: + return a + return gcd(b, a%b) + + if __name__ == "__main__": + import doctest + doctest.testmod() + +The ``testmod`` function automatically picks up all the docstrings that +have sample sessions from the interactive interpreter, executes them and +compares the output with the results as specified in the sample sessions. +If all the outputs match the expected outputs that have been documented, it +doesn't say anything. It complains only if the results don't match as +documented, expected results. + +When we execute this script as a stand-alone script we will get back the +prompt with no messages which means all the tests passed + +:: + + $ python gcd.py + $ + +If we further want to get a more detailed report of the tests that were +executed we can run python with -v as the command line option to the script + +:: + + $ python gcd.py -v + Trying: + gcd(48, 64) + Expecting: + 16 + ok + Trying: + gcd(44, 19) + Expecting: + 1 + ok + 1 items had no tests: + __main__ + 1 items passed all tests: + 2 tests in __main__.gcd + 2 tests in 2 items. + 2 passed and 0 failed. + Test passed. + + +**Note:** We can have the sample sessions as test cases as long as the +outputs of the test cases do not contain any blank lines. In such cases we +may have to use the exact string ``<BLANKLINE>`` + +For the sake of illustrating a failing test case, let us assume that we +made a small mistake in our code. Instead of returning ``a`` when b = 0, we +typed it as ``return b`` when b = 0. Now, all the GCDs returned will have +the value 0. The code looks as follows + +:: + + def gcd(a, b): + """Returns the Greatest Common Divisor of the two integers + passed as arguments. + + Args: + a: an integer + b: another integer + + Returns: Greatest Common Divisor of a and b + + >>> gcd(48, 64) + 16 + >>> gcd(44, 19) + 1 + """ + if b == 0: + return b + return gcd(b, a%b) + +Executing this code snippet without -v option to the script + +:: + + $ python gcd.py + ********************************************************************** + File "gcd.py", line 11, in __main__.gcd + Failed example: + gcd(48, 64) + Expected: + 16 + Got: + 0 + ********************************************************************** + File "gcd.py", line 13, in __main__.gcd + Failed example: + gcd(44, 19) + Expected: + 1 + Got: + 0 + ********************************************************************** + 1 items had failures: + 2 of 2 in __main__.gcd + ***Test Failed*** 2 failures. + +The output clearly complains that there were exactly two test cases +that failed. If we want a more verbose report we can pass -v option to +the script. + +This is all there is, to using the ``doctest`` module in Python. +``doctest`` is extremely useful when we want to test each Python function +or module individually. + +For more information about the doctest module refer to the Python library +reference on doctest[0]. + +unittest framework +~~~~~~~~~~~~~~~~~~ + +We needn't go too far ahead, to start complaining that ``doctest`` is not +sufficient to write complicated tests especially when we want to automate +our tests, write tests that need to test for more convoluted code pieces. +For such scenarios, Python provides a ``unittest`` framework. + +The ``unittest`` framework provides methods to efficiently automate tests, +easily initialize code and data for executing the specific tests, cleanly +shut them down once the tests are executed and easy ways of aggregating +tests into collections and better way of reporting the tests. + +Let us continue testing our gcd function in the Python module named +``gcd.py``. The ``unittest`` framework expects us to subclass the +``TestCase`` class in ``unittest`` module and place all our test code as +methods of this class. The name of the test methods are expected to be +started with ``test_``, so that the test runner knows which methods are to +be executed as tests. We shall use the test cases supplied by +``gcd_testcases.dat``. + +Lastly, to illustrate the way to test Python code as a module, let's create +a new file called ``test_gcd.py`` following the same convention used to +name the test methods, and place our test code in it. + +:: + + import gcd + import unittest + + class TestGcdFunction(unittest.TestCase): + + def setUp(self): + self.test_file = open('gcd_testcases.dat') + self.test_cases = [] + for line in self.test_file: + values = line.split(', ') + a = int(values[0]) + b = int(values[1]) + g = int(values[2]) + + self.test_cases.append([a, b, g]) + + def test_gcd(self): + for case in self.test_cases: + a = case[0] + b = case[1] + g = case[2] + self.assertEqual(gcd.gcd(a, b), g) + + def tearDown(self): + self.test_file.close() + del self.test_cases + + if __name__ == '__main__': + unittest.main() + +Please note that although we highly recommend writing docstrings for all +the classes, functions and modules, we have not done so, in this example to +keep it compact. Adding suitable docstrings wherever required is left to +you, as an exercise. + +It would be a waste, to read the test data file, each time we run a test +method. So, in the setUp method, we read all the test data and store it +into a list called test_cases, which is an attribute of the TestGCDFunction +class. In the tearDown method of the class we will delete this attribute to +free up the memory and close the opened file. + +Our actual test code sits in the method which begins with the name +``test_``, as stated earlier, the ``test_gcd`` method. Note that, we import +the ``gcd`` Python module we have written at the top of this test file and +from this test method we call the ``gcd`` function within the ``gcd`` +module to be tested with the each set of ``a`` and ``b`` values +``test_cases``. Once we execute the ``test_gcd`` function, we obtain the +result and compare it with the expected result as stored in the +corresponding ``test_cases`` attribute using the ``assertEqual`` method +provided by ``TestCase`` class in the ``unittest`` framework. There are +several other assertion methods supplied by the unittest framework. For a +more detailed information about this, refer to the unittest library +reference at [1]. This brings us to the end of our discussion of the +``unittest`` framework. + +nose +==== + +We have seen the ``unittest`` frame work and Python ``doctest`` module. . +One problem however remains. It is not easy to organize, choose and run +tests, when our code is scattered across multiple files. In the real world +scenario, this is often the case. + +In such a such a scenario, a tool which can aggregate these tests +automatically, and run them. The ``nose`` module, does precisely this, for +us. It can aggregate ``unittests`` and ``doctests`` into a collection and +run them. It also helps output the test-results and aggregate them in +various formats. + +Although nose is not part of the standard Python distribution itself, it +can be very easily installed by using easy_install command as follows + +:: + + $ easy_install nose + +Or download the nose package from [2], extracting the archive and running +the command from the extracted directory + +:: + + $ python setup.py install + +Now we have nose up and running, but how do we use it? We shall use the +``nosetests`` command provided by the ``nose`` module, in the top-level +directory of our code. + +:: + + $ nosetests + +That's all! ``nose`` will now automatically pick all the tests in all the +directories and subdirectories in our code base and execute them. + +However if we want to execute specific tests we can pass the test file +names or the directories as arguments to nosetests command. For a detailed +explanation about this, refer to [3] + +Conclusion +========== + +Now we have all the trappings we want to write state-of-the art tests. To +emphasize the same point again, any code which was written before writing +the test and the testcases in hand is flawed by design. So it is +recommended to follow the three step approach while writing code for any +project as below: + + 1. Write failing tests with testcases in hand. + 2. Write the code to pass the tests. + 3. Refactor the code for better performance. + +This approach is very famously known to the software development world as +"Red-Green-Refactor" approach[4]. + +[0] - http://docs.python.org/library/doctest.html +[1] - http://docs.python.org/library/unittest.html +[2] - http://pypi.python.org/pypi/nose/ +[3] - http://somethingaboutorange.com/mrl/projects/nose/0.11.2/usage.html +[4] - http://en.wikipedia.org/wiki/Test-driven_development + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/ult/examples/bar.txt b/lecture_notes/ult/examples/bar.txt new file mode 100644 index 0000000..c0a5b08 --- /dev/null +++ b/lecture_notes/ult/examples/bar.txt @@ -0,0 +1,8 @@ +"Bar" as the second term in the series may have developed in +electronics, where a digital signal which is considered "on" with a +negative or zero-voltage condition is identified with a horizontal bar +over the signal label; the notation for an inverted signal foo would +then be pronounced "foo bar". Bar may also be read as beyond all +repair, which is how it is used in the acronym FUBAR. + +source: wikipedia diff --git a/lecture_notes/ult/examples/foo.txt b/lecture_notes/ult/examples/foo.txt new file mode 100644 index 0000000..1fe9426 --- /dev/null +++ b/lecture_notes/ult/examples/foo.txt @@ -0,0 +1,9 @@ +FOO is an abbreviation of Forward Observation Officer, a British Army +term in use as early as the First World War. The etymology of foo is +explored in the Internet Engineering Task Force (IETF) Request for +Comments 3092, which notes usage of foo in 1930s cartoons including +The Daffy Doc (with Daffy Duck) and comic strips, especially Smokey +Stover and Pogo. From there the term migrated into military slang, +where it merged with FUBAR. + +source: wikipedia diff --git a/lecture_notes/ult/examples/items.txt b/lecture_notes/ult/examples/items.txt new file mode 100644 index 0000000..e0828ee --- /dev/null +++ b/lecture_notes/ult/examples/items.txt @@ -0,0 +1,18 @@ +Programming Pearls +The C Programming Language +The Mythical Man Month: Essays on Software Engineering +Programming Pearls +The C Programming Language +Structure and Interpretation of Computer Programs +Programming Pearls +Compilers: Principles, Techniques, and Tools +The C Programming Language +The Art of UNIX Programming +Programming Pearls +The Art of Computer Programming +Introduction to Algorithms +The Art of UNIX Programming +The Pragmatic Programmer: From Journeyman to Master +Programming Pearls +Unix Power Tools +The Art of UNIX Programming diff --git a/lecture_notes/ult/examples/marks.txt b/lecture_notes/ult/examples/marks.txt new file mode 100644 index 0000000..f97b743 --- /dev/null +++ b/lecture_notes/ult/examples/marks.txt @@ -0,0 +1,5 @@ +89 92 85 +98 47 67 +67 82 76 +78 97 60 +67 68 69 diff --git a/lecture_notes/ult/examples/marks1.txt b/lecture_notes/ult/examples/marks1.txt new file mode 100644 index 0000000..9a5299d --- /dev/null +++ b/lecture_notes/ult/examples/marks1.txt @@ -0,0 +1,5 @@ +5 89 92 85 +4 98 47 67 +1 67 82 76 +2 78 97 60 +3 67 68 69 diff --git a/lecture_notes/ult/examples/primes.txt b/lecture_notes/ult/examples/primes.txt new file mode 100644 index 0000000..b5cdec8 --- /dev/null +++ b/lecture_notes/ult/examples/primes.txt @@ -0,0 +1,30 @@ +2 +3 +5 +7 +11 +13 +17 +19 +23 +29 +31 +37 +41 +43 +47 +53 +59 +61 +67 +71 +73 +79 +83 +89 +97 +101 +103 +107 +109 +113 diff --git a/lecture_notes/ult/examples/students.txt b/lecture_notes/ult/examples/students.txt new file mode 100644 index 0000000..ddacd6b --- /dev/null +++ b/lecture_notes/ult/examples/students.txt @@ -0,0 +1,5 @@ +Hussain +Dilbert +Anne +Raul +Sven diff --git a/lecture_notes/ult/examples/wonderland.txt b/lecture_notes/ult/examples/wonderland.txt new file mode 100644 index 0000000..0f62284 --- /dev/null +++ b/lecture_notes/ult/examples/wonderland.txt @@ -0,0 +1,4047 @@ +Project Gutenberg's Alice's Adventures in Wonderland, by Lewis Carroll
+
+This eBook is for the use of anyone anywhere at no cost and with
+almost no restrictions whatsoever. You may copy it, give it away or
+re-use it under the terms of the Project Gutenberg License included
+with this eBook or online at www.gutenberg.net
+
+
+Title: Alice's Adventures in Wonderland
+ Illustrated by Arthur Rackham. With a Proem by Austin Dobson
+
+Author: Lewis Carroll
+
+Illustrator: Arthur Rackham
+
+Release Date: May 19, 2009 [EBook #28885]
+
+Language: English
+
+Character set encoding: ISO-8859-1
+
+*** START OF THIS PROJECT GUTENBERG EBOOK ALICE'S ADVENTURES IN WONDERLAND ***
+
+
+
+
+Produced by Jana Srna, Emmy and the Online Distributed
+Proofreading Team at http://www.pgdp.net (This file was
+produced from images generously made available by the
+University of Florida Digital Collections.)
+
+
+
+
+
+
+
+
+
+
+
+ALICE'S ADVENTURES IN WONDERLAND
+
+[Illustration: "Alice"]
+
+[Illustration:
+
+ ALICE'S·ADVENTURES
+ IN·WONDERLAND
+ BY·LEWIS·CARROLL
+ ILLUSTRATED·BY
+ ARTHUR·RACKHAM
+
+ WITH A PROEM BY AUSTIN DOBSON
+
+ LONDON·WILLIAM·HEINEMANN
+ NEW·YORK·DOUBLEDAY·PAGE·&·Co]
+
+ PRINTED IN ENGLAND
+
+ _'Tis two score years since CARROLL'S art,
+ With topsy-turvy magic,
+ Sent ALICE wondering through a part
+ Half-comic and half-tragic._
+
+ _Enchanting ALICE! Black-and-white
+ Has made your deeds perennial;
+ And naught save "Chaos and old Night"
+ Can part you now from TENNIEL;_
+
+ _But still you are a Type, and based
+ In Truth, like LEAR and HAMLET;
+ And Types may be re-draped to taste
+ In cloth-of-gold or camlet._
+
+ _Here comes afresh Costumier, then;
+ That Taste may gain a wrinkle
+ From him who drew with such deft pen
+ The rags of RIP VAN WINKLE!_
+
+ _AUSTIN DOBSON._
+
+
+
+ All in the golden afternoon
+ Full leisurely we glide;
+ For both our oars, with little skill,
+ By little arms are plied,
+ While little hands make vain pretence
+ Our wanderings to guide.
+
+ Ah, cruel Three! In such an hour,
+ Beneath such dreamy weather,
+ To beg a tale of breath too weak
+ To stir the tiniest feather!
+ Yet what can one poor voice avail
+ Against three tongues together?
+
+ Imperious Prima flashes forth
+ Her edict "to begin it"--
+ In gentler tone Secunda hopes
+ "There will be nonsense in it!"--
+ While Tertia interrupts the tale
+ Not _more_ than once a minute.
+
+ Anon, to sudden silence won,
+ In fancy they pursue
+ The dream-child moving through a land
+ Of wonders wild and new,
+ In friendly chat with bird or beast--
+ And half believe it true.
+
+ And ever, as the story drained
+ The wells of fancy dry.
+ And faintly strove that weary one
+ To put the subject by,
+ "The rest next time--" "It _is_ next time!"
+ The happy voices cry.
+
+ Thus grew the tale of Wonderland:
+ Thus slowly, one by one,
+ Its quaint events were hammered out--
+ And now the tale is done,
+ And home we steer, a merry crew,
+ Beneath the setting sun.
+
+ Alice! a childish story take,
+ And with a gentle hand
+ Lay it where Childhood's dreams are twined
+ In Memory's mystic band,
+ Like pilgrim's wither'd wreath of flowers
+ Pluck'd in a far-off land.
+
+
+
+
+CONTENTS
+
+
+ PAGE
+
+ I. DOWN THE RABBIT-HOLE 1
+
+ II. THE POOL OF TEARS 13
+
+ III. A CAUCUS-RACE AND A LONG TALE 24
+
+ IV. THE RABBIT SENDS IN A LITTLE BILL 35
+
+ V. ADVICE FROM A CATERPILLAR 49
+
+ VI. PIG AND PEPPER 64
+
+ VII. A MAD TEA-PARTY 82
+
+ VIII. THE QUEEN'S CROQUET-GROUND 96
+
+ IX. THE MOCK TURTLE'S STORY 111
+
+ X. THE LOBSTER QUADRILLE 126
+
+ XI. WHO STOLE THE TARTS? 139
+
+ XII. ALICE'S EVIDENCE 150
+
+
+
+
+LIST OF THE PLATES
+
+
+ _To face page_
+
+ Alice _Frontispiece_
+
+ The Pool of Tears 22
+
+ They all crowded round it panting and
+ asking, "But who has won?" 28
+
+ "Why, Mary Ann, what are you doing out
+ here?" 36
+
+ Advice from a Caterpillar 50
+
+ An unusually large saucepan flew close
+ by it, and very nearly carried it off 70
+
+ It grunted again so violently that she
+ looked down into its face in some alarm 74
+
+ A Mad Tea-Party 84
+
+ The Queen turned angrily away from him
+ and said to the Knave, "Turn them over" 100
+
+ The Queen never left off quarrelling
+ with the other players, and shouting
+ "Off with his head!" or, "Off with her
+ head!" 116
+
+ The Mock Turtle drew a long breath and
+ said, "That's very curious" 132
+
+ Who stole the Tarts? 140
+
+ At this the whole pack rose up into the
+ air, and came flying down upon her 158
+
+
+
+
+CHAPTER I
+
+
+[Sidenote: _Down the Rabbit-Hole_]
+
+ALICE was beginning to get very tired of sitting by her
+sister on the bank, and of having nothing to do: once or twice she had
+peeped into the book her sister was reading, but it had no pictures or
+conversations in it, "and what is the use of a book," thought Alice,
+"without pictures or conversations?"
+
+So she was considering in her own mind (as well as she could, for the
+hot day made her feel very sleepy and stupid) whether the pleasure of
+making a daisy-chain would be worth the trouble of getting up and
+picking the daisies, when suddenly a White Rabbit with pink eyes ran
+close by her.
+
+There was nothing so _very_ remarkable in that; nor did Alice think it
+so _very_ much out of the way to hear the Rabbit say to itself, "Oh
+dear! Oh dear! I shall be too late!" (when she thought it over
+afterwards, it occurred to her that she ought to have wondered at this,
+but at the time it all seemed quite natural); but when the Rabbit
+actually _took a watch out of its waistcoat-pocket_, and looked at it,
+and then hurried on, Alice started to her feet, for it flashed across
+her mind that she had never before seen a rabbit with either a
+waistcoat-pocket, or a watch to take out of it, and burning with
+curiosity, she ran across the field after it, and was just in time to
+see it pop down a large rabbit-hole under the hedge.
+
+In another moment down went Alice after it, never once considering how
+in the world she was to get out again.
+
+The rabbit-hole went straight on like a tunnel for some way, and then
+dipped suddenly down, so suddenly that Alice had not a moment to think
+about stopping herself before she found herself falling down what seemed
+to be a very deep well.
+
+[Illustration]
+
+Either the well was very deep, or she fell very slowly, for she had
+plenty of time as she went down to look about her, and to wonder what
+was going to happen next. First, she tried to look down and make out
+what she was coming to, but it was too dark to see anything; then she
+looked at the sides of the well and noticed that they were filled with
+cupboards and book-shelves: here and there she saw maps and pictures
+hung upon pegs. She took down a jar from one of the shelves as she
+passed; it was labelled "ORANGE MARMALADE," but to her disappointment it
+was empty; she did not like to drop the jar for fear of killing
+somebody underneath, so managed to put it into one of the cupboards as
+she fell past it.
+
+"Well!" thought Alice to herself. "After such a fall as this, I shall
+think nothing of tumbling down stairs! How brave they'll all think me at
+home! Why, I wouldn't say anything about it, even if I fell off the top
+of the house!" (Which was very likely true.)
+
+Down, down, down. Would the fall _never_ come to an end? "I wonder how
+many miles I've fallen by this time?" she said aloud. "I must be getting
+somewhere near the centre of the earth. Let me see: that would be four
+thousand miles down. I think--" (for, you see, Alice had learnt several
+things of this sort in her lessons in the schoolroom, and though this
+was not a _very_ good opportunity for showing off her knowledge, as
+there was no one to listen to her, still it was good practice to say it
+over) "--yes, that's about the right distance--but then I wonder what
+Latitude or Longitude I've got to?" (Alice had no idea what Latitude
+was, or Longitude either, but thought they were nice grand words to
+say.)
+
+Presently she began again. "I wonder if I shall fall right _through_ the
+earth! How funny it'll seem to come out among the people that walk with
+their heads downwards! The Antipathies, I think--" (she was rather glad
+there _was_ no one listening, this time, as it didn't sound at all the
+right word) "--but I shall have to ask them what the name of the country
+is, you know. Please, Ma'am, is this New Zealand or Australia?" (and she
+tried to curtsey as she spoke--fancy _curtseying_ as you're falling
+through the air! Do you think you could manage it?) "And what an
+ignorant little girl she'll think me! No, it'll never do to ask: perhaps
+I shall see it written up somewhere."
+
+Down, down, down. There was nothing else to do, so Alice soon began
+talking again. "Dinah'll miss me very much to-night, I should think!"
+(Dinah was the cat.) "I hope they'll remember her saucer of milk at
+tea-time. Dinah, my dear, I wish you were down here with me! There are
+no mice in the air, I'm afraid, but you might catch a bat, and that's
+very like a mouse, you know. But do cats eat bats, I wonder?" And here
+Alice began to get rather sleepy, and went on saying to herself, in a
+dreamy sort of way, "Do cats eat bats? Do cats eat bats?" and sometimes,
+"Do bats eat cats?" for, you see, as she couldn't answer either
+question, it didn't much matter which way she put it. She felt that she
+was dozing off, and had just begun to dream that she was walking hand in
+hand with Dinah, and saying to her very earnestly, "Now, Dinah, tell me
+the truth: did you ever eat a bat?" when suddenly, thump! thump! down
+she came upon a heap of sticks and dry leaves, and the fall was over.
+
+Alice was not a bit hurt, and she jumped up on to her feet in a moment:
+she looked up, but it was all dark overhead; before her was another long
+passage, and the White Rabbit was still in sight, hurrying down it.
+There was not a moment to be lost: away went Alice like the wind, and
+was just in time to hear it say, as it turned a corner, "Oh my ears and
+whiskers, how late it's getting!" She was close behind it when she
+turned the corner, but the Rabbit was no longer to be seen: she found
+herself in a long, low hall, which was lit up by a row of lamps hanging
+from the roof.
+
+There were doors all round the hall, but they were all locked; and when
+Alice had been all the way down one side and up the other, trying every
+door, she walked sadly down the middle, wondering how she was ever to
+get out again.
+
+Suddenly she came upon a little three-legged table, all made of solid
+glass; there was nothing on it but a tiny golden key, and Alice's first
+idea was that this might belong to one of the doors of the hall; but,
+alas! either the locks were too large, or the key was too small, but at
+any rate it would not open any of them. However, on the second time
+round, she came upon a low curtain she had not noticed before, and
+behind it was a little door about fifteen inches high: she tried the
+little golden key in the lock, and to her great delight it fitted!
+
+Alice opened the door and found that it led into a small passage, not
+much larger than a rat-hole: she knelt down and looked along the passage
+into the loveliest garden you ever saw. How she longed to get out of
+that dark hall, and wander about among those beds of bright flowers and
+those cool fountains, but she could not even get her head through the
+doorway; "and even if my head would go through," thought poor Alice, "it
+would be of very little use without my shoulders. Oh, how I wish I could
+shut up like a telescope! I think I could, if I only knew how to begin."
+For, you see, so many out-of-the-way things had happened lately, that
+Alice had begun to think that very few things indeed were really
+impossible.
+
+There seemed to be no use in waiting by the little door, so she went
+back to the table, half hoping she might find another key on it, or at
+any rate a book of rules for shutting people up like telescopes: this
+time she found a little bottle on it ("which certainly was not here
+before," said Alice,) and tied round the neck of the bottle was a paper
+label, with the words "DRINK ME" beautifully printed on it in large
+letters.
+
+It was all very well to say "Drink me," but the wise little Alice was
+not going to do _that_ in a hurry. "No, I'll look first," she said, "and
+see whether it's marked '_poison_' or not;" for she had read several
+nice little stories about children who had got burnt, and eaten up by
+wild beasts, and other unpleasant things, all because they _would_ not
+remember the simple rules their friends had taught them: such as, that a
+red-hot poker will burn you if you hold it too long; and that, if you
+cut your finger _very_ deeply with a knife, it usually bleeds; and she
+had never forgotten that, if you drink much from a bottle marked
+"poison," it is almost certain to disagree with you, sooner or later.
+
+However, this bottle was _not_ marked "poison," so Alice ventured to
+taste it, and finding it very nice (it had, in fact, a sort of mixed
+flavour of cherry-tart, custard, pineapple, roast turkey, coffee, and
+hot buttered toast,) she very soon finished it off.
+
+ * * * * *
+
+"What a curious feeling!" said Alice. "I must be shutting up like a
+telescope."
+
+And so it was indeed: she was now only ten inches high, and her face
+brightened up at the thought that she was now the right size for going
+through that little door into that lovely garden. First, however, she
+waited for a few minutes to see if she was going to shrink any further:
+she felt a little nervous about this: "for it might end, you know," said
+Alice to herself, "in my going out altogether, like a candle. I wonder
+what I should be like then?" And she tried to fancy what the flame of a
+candle looks like after the candle is blown out, for she could not
+remember ever having seen such a thing.
+
+After a while, finding that nothing more happened, she decided on going
+into the garden at once; but, alas for poor Alice! when she got to the
+door, she found she had forgotten the little golden key, and when she
+went back to the table for it, she found she could not possibly reach
+it: she could see it quite plainly through the glass, and she tried her
+best to climb up one of the legs of the table, but it was too slippery;
+and when she had tired herself out with trying, the poor little thing
+sat down and cried.
+
+"Come, there's no use in crying like that!" said Alice to herself,
+rather sharply. "I advise you to leave off this minute!" She generally
+gave herself very good advice (though she very seldom followed it), and
+sometimes she scolded herself so severely as to bring tears into her
+eyes; and once she remembered trying to box her own ears for having
+cheated herself in a game of croquet she was playing against herself,
+for this curious child was very fond of pretending to be two people.
+"But it's no use now," thought poor Alice, "to pretend to be two people!
+Why there's hardly enough of me left to make _one_ respectable person!"
+
+Soon her eye fell on a little glass box that was lying under the table:
+she opened it, and found in it a very small cake, on which the words
+"EAT ME" were beautifully marked in currants. "Well, I'll eat it," said
+Alice, "and if it makes me grow larger, I can reach the key; and if it
+makes me grow smaller, I can creep under the door; so either way I'll
+get into the garden, and I don't care which happens!"
+
+She ate a little bit, and said anxiously to herself, "Which way? Which
+way?" holding her hand on the top of her head to feel which way it was
+growing, and she was quite surprised to find that she remained the same
+size; to be sure, this is what generally happens when one eats cake,
+but Alice had got so much into the way of expecting nothing but
+out-of-the-way things to happen, that it seemed quite dull and stupid
+for life to go on in the common way.
+
+So she set to work, and very soon finished off the cake.
+
+ * * * * *
+
+
+
+
+CHAPTER II
+
+
+[Sidenote: _Pool of Tears_]
+
+"CURIOUSER and curiouser!" cried Alice (she was so much
+surprised, that for a moment she quite forgot how to speak good
+English); "now I'm opening out like the largest telescope that ever was!
+Good-bye, feet!" (for when she looked down at her feet, they seemed to
+be almost out of sight, they were getting so far off). "Oh, my poor
+little feet, I wonder who will put on your shoes and stockings for you
+now, dears? I'm sure _I_ sha'n't be able! I shall be a great deal too
+far off to trouble myself about you: you must manage the best way you
+can--but I must be kind to them," thought Alice, "or perhaps they won't
+walk the way I want to go! Let me see: I'll give them a new pair of
+boots every Christmas."
+
+And she went on planning to herself how she would manage it. "They must
+go by the carrier," she thought; "and how funny it'll seem, sending
+presents to one's own feet! And how odd the directions will look!
+
+ Alice's Right Foot, Esq.
+ Hearthrug,
+ near the Fender,
+ (with Alice's love).
+
+Oh dear, what nonsense I'm talking!"
+
+Just then her head struck against the roof of the hall: in fact she was
+now rather more than nine feet high, and she at once took up the little
+golden key and hurried off to the garden door.
+
+Poor Alice! It was as much as she could do, lying down on one side, to
+look through into the garden with one eye; but to get through was more
+hopeless than ever: she sat down and began to cry again.
+
+"You ought to be ashamed of yourself," said Alice, "a great girl like
+you" (she might well say this), "to go on crying in this way! Stop this
+moment, I tell you!" But she went on all the same, shedding gallons of
+tears, until there was a large pool all round her, about four inches
+deep and reaching half down the hall.
+
+[Illustration: CURIOUSER AND CURIOUSER]
+
+After a time she heard a little pattering of feet in the distance, and
+she hastily dried her eyes to see what was coming. It was the White
+Rabbit returning, splendidly dressed, with a pair of white kid gloves in
+one hand and a large fan in the other: he came trotting along in a great
+hurry, muttering to himself as he came, "Oh! the Duchess, the Duchess!
+Oh! won't she be savage if I've kept her waiting!" Alice felt so
+desperate that she was ready to ask help of any one; so, when the
+Rabbit came near her, she began, in a low, timid voice, "If you please,
+sir----" The Rabbit started violently, dropped the white kid gloves and
+the fan, and scurried away into the darkness as hard as he could go.
+
+Alice took up the fan and gloves, and, as the hall was very hot, she
+kept fanning herself all the time she went on talking! "Dear, dear! How
+queer everything is to-day! And yesterday things went on just as usual.
+I wonder if I've been changed during the night? Let me think: _was_ I
+the same when I got up this morning? I almost think I can remember
+feeling a little different. But if I'm not the same, the next question
+is, who in the world am I? Ah, _that's_ the great puzzle!" And she began
+thinking over all the children she knew that were of the same age as
+herself, to see if she could have been changed for any of them.
+
+"I'm sure I'm not Ada," she said, "for her hair goes in such long
+ringlets, and mine doesn't go in ringlets at all; and I'm sure I can't
+be Mabel, for I know all sorts of things, and she, oh! she knows such a
+very little! Besides, _she's_ she, and _I'm_ I, and--oh dear, how
+puzzling it all is! I'll try if I know all the things I used to know.
+Let me see: four times five is twelve, and four times six is thirteen,
+and four times seven is--oh dear! I shall never get to twenty at that
+rate! However, the Multiplication Table doesn't signify: let's try
+Geography. London is the capital of Paris, and Paris is the capital of
+Rome, and Rome--no, _that's_ all wrong, I'm certain! I must have been
+changed for Mabel! I'll try and say '_How doth the little----_'" and she
+crossed her hands on her lap as if she were saying lessons, and began to
+repeat it, but her voice sounded hoarse and strange, and the words did
+not come the same as they used to do:--
+
+ "How doth the little crocodile
+ Improve his shining tail,
+ And pour the waters of the Nile
+ On every golden scale!
+
+ "How cheerfully he seems to grin,
+ How neatly spreads his claws,
+ And welcomes little fishes in,
+ With gently smiling jaws!"
+
+"I'm sure those are not the right words," said poor Alice, and her eyes
+filled with tears again as she went on. "I must be Mabel, after all, and
+I shall have to go and live in that poky little house, and have next to
+no toys to play with, and oh! ever so many lessons to learn! No, I've
+made up my mind about it; if I'm Mabel, I'll stay down here! It'll be no
+use their putting their heads down and saying, 'Come up again, dear!' I
+shall only look up and say, 'Who am I then? Tell me that first, and
+then, if I like being that person, I'll come up: if not, I'll stay down
+here till I'm somebody else'--but, oh dear!" cried Alice with a sudden
+burst of tears, "I do wish they _would_ put their heads down! I am so
+_very_ tired of being all alone here!"
+
+As she said this she looked down at her hands, and was surprised to see
+that she had put on one of the Rabbit's little white kid gloves while
+she was talking. "How _can_ I have done that?" she thought. "I must be
+growing small again." She got up and went to the table to measure
+herself by it, and found that, as nearly as she could guess, she was now
+about two feet high, and was going on shrinking rapidly: she soon found
+out that the cause of this was the fan she was holding, and she dropped
+it hastily, just in time to avoid shrinking away altogether.
+
+"That _was_ a narrow escape!" said Alice, a good deal frightened at the
+sudden change, but very glad to find herself still in existence; "and
+now for the garden!" and she ran with all speed back to the little door:
+but alas! the little door was shut again, and the little golden key was
+lying on the glass table as before, "and things are worse than ever,"
+thought the poor child, "for I never was so small as this before, never!
+And I declare it's too bad, that it is!"
+
+As she said these words her foot slipped, and in another moment, splash!
+she was up to her chin in salt water. Her first idea was that she had
+somehow fallen into the sea, "and in that case I can go back by
+railway," she said to herself. (Alice had been to the seaside once in
+her life, and had come to the general conclusion, that wherever you go
+to on the English coast you find a number of bathing machines in the
+sea, some children digging in the sand with wooden spades, then a row
+of lodging houses, and behind them a railway station.) However, she soon
+made out that she was in the pool of tears which she had wept when she
+was nine feet high.
+
+"I wish I hadn't cried so much!" said Alice, as she swam about, trying
+to find her way out. "I shall be punished for it now, I suppose, by
+being drowned in my own tears! That _will_ be a queer thing, to be sure!
+However, everything is queer to-day."
+
+Just then she heard something splashing about in the pool a little way
+off, and she swam nearer to make out what it was: at first she thought
+it must be a walrus or hippopotamus, but then she remembered how small
+she was now, and she soon made out that it was only a mouse that had
+slipped in like herself.
+
+"Would it be of any use now," thought Alice, "to speak to this mouse?
+Everything is so out-of-the-way down here, that I should think very
+likely it can talk: at any rate, there's no harm in trying." So she
+began: "O Mouse, do you know the way out of this pool? I am very tired
+of swimming about here, O Mouse!" (Alice thought this must be the right
+way of speaking to a mouse; she had never done such a thing before, but
+she remembered having seen in her brother's Latin Grammar, "A mouse--of
+a mouse--to a mouse--a mouse--O mouse!") The Mouse looked at her rather
+inquisitively, and seemed to her to wink with one of its little eyes,
+but it said nothing.
+
+"Perhaps it doesn't understand English," thought Alice; "I daresay it's
+a French mouse, come over with William the Conqueror." (For, with all
+her knowledge of history, Alice had no very clear notion how long ago
+anything had happened.) So she began again: "Où est ma chatte?" which
+was the first sentence in her French lesson-book. The Mouse gave a
+sudden leap out of the water, and seemed to quiver all over with fright.
+"Oh, I beg your pardon!" cried Alice hastily, afraid that she had hurt
+the poor animal's feelings. "I quite forgot you didn't like cats."
+
+"Not like cats!" cried the Mouse, in a shrill, passionate voice. "Would
+_you_ like cats if you were me?"
+
+"Well, perhaps not," said Alice in a soothing tone: "don't be angry
+about it. And yet I wish I could show you our cat Dinah: I think you'd
+take a fancy to cats if you could only see her. She is such a dear quiet
+thing," Alice went on, half to herself, as she swam lazily about in the
+pool, "and she sits purring so nicely by the fire, licking her paws and
+washing her face--and she is such a nice soft thing to nurse--and she's
+such a capital one for catching mice----oh, I beg your pardon!" cried
+Alice again, for this time the Mouse was bristling all over, and she
+felt certain it must be really offended. "We won't talk about her any
+more if you'd rather not."
+
+"We, indeed!" cried the Mouse, who was trembling down to the end of his
+tail. "As if _I_ would talk on such a subject! Our family always _hated_
+cats: nasty, low, vulgar things! Don't let me hear the name again!"
+
+[Illustration: _The Pool of Tears_]
+
+"I won't indeed!" said Alice, in a great hurry to change the subject of
+conversation. "Are you--are you fond--of--of dogs?" The Mouse did not
+answer, so Alice went on eagerly: "There is such a nice little dog near
+our house I should like to show you! A little bright-eyed terrier, you
+know, with oh, such long curly brown hair! And it'll fetch things
+when you throw them, and it'll sit up and beg for its dinner, and all
+sorts of things--I can't remember half of them--and it belongs to a
+farmer, you know, and he says it's so useful, it's worth a hundred
+pounds! He says it kills all the rats and--oh dear!" cried Alice in a
+sorrowful tone, "I'm afraid I've offended it again!" For the Mouse was
+swimming away from her as hard as it could go, and making quite a
+commotion in the pool as it went.
+
+So she called softly after it, "Mouse dear! Do come back again, and we
+won't talk about cats or dogs either, if you don't like them!"
+
+When the Mouse heard this, it turned round and swam slowly back to her:
+its face was quite pale (with passion, Alice thought), and it said in a
+low trembling voice, "Let us get to the shore, and then I'll tell you my
+history, and you'll understand why it is I hate cats and dogs."
+
+It was high time to go, for the pool was getting quite crowded with the
+birds and animals that had fallen into it: there were a Duck and a Dodo,
+a Lory and an Eaglet, and several other curious creatures. Alice led the
+way, and the whole party swam to the shore.
+
+
+
+
+CHAPTER III
+
+
+[Sidenote: _A Caucus-race and a Long Tale_]
+
+THEY were indeed a queer-looking party that assembled on
+the bank--the birds with draggled feathers, the animals with their fur
+clinging close to them, and all dripping wet, cross, and uncomfortable.
+
+The first question of course was, how to get dry again: they had a
+consultation about this, and after a few minutes it seemed quite natural
+to Alice to find herself talking familiarly with them, as if she had
+known them all her life. Indeed, she had quite a long argument with the
+Lory, who at last turned sulky, and would only say, "I am older than
+you, and must know better;" and this Alice would not allow without
+knowing how old it was, and, as the Lory positively refused to tell its
+age, there was no more to be said.
+
+At last the Mouse, who seemed to be a person of authority among them,
+called out "Sit down, all of you, and listen to me! _I'll_ soon make you
+dry enough!" They all sat down at once, in a large ring, with the Mouse
+in the middle. Alice kept her eyes anxiously fixed on it, for she felt
+sure she would catch a bad cold if she did not get dry very soon.
+
+"Ahem!" said the Mouse with an important air. "Are you all ready? This
+is the driest thing I know. Silence all round, if you please! 'William
+the Conqueror, whose cause was favoured by the pope, was soon submitted
+to by the English, who wanted leaders, and had been of late much
+accustomed to usurpation and conquest. Edwin and Morcar, the earls of
+Mercia and Northumbria--'"
+
+"Ugh!" said the Lory, with a shiver.
+
+"I beg your pardon!" said the Mouse, frowning, but very politely. "Did
+you speak?"
+
+"Not I!" said the Lory hastily.
+
+"I thought you did," said the Mouse, "--I proceed. 'Edwin and Morcar,
+the earls of Mercia and Northumbria, declared for him: and even
+Stigand, the patriotic Archbishop of Canterbury, found it advisable--'"
+
+"Found _what_?" said the Duck.
+
+"Found _it_," the Mouse replied rather crossly: "of course you know what
+'it' means."
+
+"I know what 'it' means well enough, when _I_ find a thing," said the
+Duck; "it's generally a frog or a worm. The question is, what did the
+archbishop find?"
+
+The Mouse did not notice this question, but hurriedly went on, "'--found
+it advisable to go with Edgar Atheling to meet William and offer him the
+crown. William's conduct at first was moderate. But the insolence of his
+Normans--' How are you getting on now, my dear?" it continued, turning
+to Alice as it spoke.
+
+"As wet as ever," said Alice in a melancholy tone; "doesn't seem to dry
+me at all."
+
+"In that case," said the Dodo solemnly, rising to its feet, "I move that
+the meeting adjourn, for the immediate adoption of more energetic
+remedies----"
+
+"Speak English!" said the Eaglet. "I don't know the meaning of half
+those long words, and, what's more, I don't believe you do either!" And
+the Eaglet bent down its head to hide a smile: some of the other birds
+tittered audibly.
+
+"What I was going to say," said the Dodo in an offended tone, "was that
+the best thing to get us dry would be a Caucus-race."
+
+"What _is_ a Caucus-race?" said Alice; not that she much wanted to know,
+but the Dodo had paused as if it thought that _somebody_ ought to speak,
+and no one else seemed inclined to say anything.
+
+"Why," said the Dodo, "the best way to explain it is to do it." (And, as
+you might like to try the thing yourself some winter day, I will tell
+you how the Dodo managed it.)
+
+First it marked out a race-course, in a sort of circle, ("the exact
+shape doesn't matter," it said,) and then all the party were placed
+along the course, here and there. There was no "One, two, three, and
+away," but they began running when they liked, and left off when they
+liked, so that it was not easy to know when the race was over. However,
+when they had been running half an hour or so, and were quite dry again,
+the Dodo suddenly called "The race is over!" and they all crowded round
+it, panting, and asking "But who has won?"
+
+This question the Dodo could not answer without a great deal of thought,
+and it stood for a long time with one finger pressed upon its forehead
+(the position in which you usually see Shakespeare, in the pictures of
+him), while the rest waited in silence. At last the Dodo said
+"_Everybody_ has won, and _all_ must have prizes."
+
+"But who is to give the prizes?" quite a chorus of voices asked.
+
+"Why, _she_, of course," said the Dodo, pointing to Alice with one
+finger; and the whole party at once crowded round her, calling out in a
+confused way, "Prizes! Prizes!"
+
+Alice had no idea what to do, and in despair she put her hand in her
+pocket, and pulled out a box of comfits (luckily the salt water had not
+got into it), and handed them round as prizes. There was exactly one
+apiece all round.
+
+ _They all crowded round it panting and asking,
+ "But who has won?"_
+
+[Illustration]
+
+"But she must have a prize herself, you know," said the Mouse.
+
+"Of course," the Dodo replied very gravely.
+
+"What else have you got in your pocket?" it went on, turning to Alice.
+
+"Only a thimble," said Alice sadly.
+
+"Hand it over here," said the Dodo.
+
+Then they all crowded round her once more, while the Dodo solemnly
+presented the thimble, saying "We beg your acceptance of this elegant
+thimble;" and, when it had finished this short speech, they all cheered.
+
+Alice thought the whole thing very absurd, but they all looked so grave
+that she did not dare to laugh; and, as she could not think of anything
+to say, she simply bowed, and took the thimble, looking as solemn as she
+could.
+
+The next thing was to eat the comfits; this caused some noise and
+confusion, as the large birds complained that they could not taste
+theirs, and the small ones choked and had to be patted on the back.
+However, it was over at last, and they sat down again in a ring, and
+begged the Mouse to tell them something more.
+
+"You promised to tell me your history, you know," said Alice, "and why
+it is you hate--C and D," she added in a whisper, half afraid that it
+would be offended again.
+
+[Illustration]
+
+"Mine is a long and sad tale!" said the Mouse, turning to Alice and
+sighing.
+
+"It _is_ a long tail, certainly," said Alice, looking down with wonder
+at the Mouse's tail; "but why do you call it sad?" And she kept on
+puzzling about it while the Mouse was speaking, so that her idea of the
+tale was something like this:--
+
+ "Fury said to
+ a mouse, That
+ he met in the
+ house, 'Let
+ us both go
+ to law: _I_
+ will prose-
+ cute _you_.--
+ Come, I'll
+ take no de-
+ nial: We
+ must have
+ the trial;
+ For really
+ this morn-
+ ing I've
+ nothing
+ to do.'
+ Said the
+ mouse to
+ the cur,
+ 'Such a
+ trial, dear
+ sir, With
+ no jury
+ or judge,
+ would
+ be wast-
+ ing our
+ breath.'
+ 'I'll be
+ judge,
+ I'll be
+ jury,'
+ said
+ cun-
+ ning
+ old
+ Fury:
+ 'I'll
+ try
+ the
+ whole
+ cause,
+ and
+ con-
+ demn
+ you to
+ death.'
+
+"You are not attending!" said the Mouse to Alice severely. "What are you
+thinking of?"
+
+"I beg your pardon," said Alice very humbly: "you had got to the fifth
+bend, I think?"
+
+"I had _not_!" cried the Mouse, angrily.
+
+"A knot!" said Alice, always ready to make herself useful, and looking
+anxiously about her. "Oh, do let me help to undo it!"
+
+"I shall do nothing of the sort," said the Mouse, getting up and walking
+away. "You insult me by talking such nonsense!"
+
+"I didn't mean it!" pleaded poor Alice. "But you're so easily offended,
+you know!"
+
+The Mouse only growled in reply.
+
+"Please come back and finish your story!" Alice called after it. And the
+others all joined in chorus, "Yes, please do!" but the Mouse only shook
+its head impatiently and walked a little quicker.
+
+"What a pity it wouldn't stay!" sighed the Lory, as soon as it was quite
+out of sight; and an old Crab took the opportunity of saying to her
+daughter, "Ah, my dear! Let this be a lesson to you never to lose
+_your_ temper!" "Hold your tongue, Ma!" said the young Crab, a little
+snappishly. "You're enough to try the patience of an oyster!"
+
+"I wish I had our Dinah here, I know I do!" said Alice aloud, addressing
+nobody in particular. "She'd soon fetch it back!"
+
+"And who is Dinah, if I might venture to ask the question?" said the
+Lory.
+
+Alice replied eagerly, for she was always ready to talk about her pet:
+"Dinah's our cat. And she's such a capital one for catching mice, you
+ca'n't think! And oh, I wish you could see her after the birds! Why,
+she'll eat a little bird as soon as look at it!"
+
+This speech caused a remarkable sensation among the party. Some of the
+birds hurried off at once; one old Magpie began wrapping itself up very
+carefully, remarking "I really must be getting home; the night-air
+doesn't suit my throat!" and a Canary called out in a trembling voice to
+its children "Come away, my dears! It's high time you were all in bed!"
+On various pretexts they all moved off, and Alice was soon left alone.
+
+"I wish I hadn't mentioned Dinah!" she said to herself in a melancholy
+tone. "Nobody seems to like her, down here, and I'm sure she's the best
+cat in the world! Oh, my dear Dinah! I wonder if I shall ever see you
+any more!" And here poor Alice began to cry again, for she felt very
+lonely and low-spirited. In a little while, however, she again heard a
+little pattering of footsteps in the distance, and she looked up
+eagerly, half hoping that the Mouse had changed his mind, and was coming
+back to finish his story.
+
+
+
+
+CHAPTER IV
+
+
+[Sidenote: _The Rabbit sends in a Little Bill_]
+
+IT was the White Rabbit, trotting slowly back again, and
+looking anxiously about as it went, as if it had lost something; and she
+heard it muttering to itself, "The Duchess! The Duchess! Oh my dear
+paws! Oh my fur and whiskers! She'll get me executed, as sure as ferrets
+are ferrets! Where _can_ I have dropped them, I wonder?" Alice guessed
+in a moment that it was looking for the fan and the pair of white kid
+gloves, and she very good-naturedly began hunting about for them, but
+they were nowhere to be seen--everything seemed to have changed since
+her swim in the pool, and the great hall, with the glass table and the
+little door, had vanished completely.
+
+Very soon the Rabbit noticed Alice, as she went hunting about, and
+called out to her in an angry tone, "Why, Mary Ann, what _are_ you
+doing out here? Run home this moment, and fetch me a pair of gloves and
+a fan! Quick, now!" And Alice was so much frightened that she ran off at
+once in the direction it pointed to, without trying to explain the
+mistake it had made.
+
+"He took me for his housemaid," she said to herself as she ran. "How
+surprised he'll be when he finds out who I am! But I'd better take him
+his fan and gloves--that is, if I can find them." As she said this, she
+came upon a neat little house, on the door of which was a bright brass
+plate with the name "W. RABBIT" engraved upon it. She went in without
+knocking, and hurried up stairs, in great fear lest she should meet the
+real Mary Ann, and be turned out of the house before she had found the
+fan and gloves.
+
+[Illustration: "_Why, Mary Ann, what are you doing out here?_"]
+
+"How queer it seems," Alice said to herself, "to be going messages for a
+rabbit! I suppose Dinah'll be sending me on messages next!" And she
+began fancying the sort of thing that would happen: "'Miss Alice! Come
+here directly, and get ready for your walk!' 'Coming in a minute, nurse!
+But I've got to watch this mouse-hole till Dinah comes back, and see
+that the mouse doesn't get out.' Only I don't think," Alice went on,
+"that they'd let Dinah stop in the house if it began ordering people
+about like that!"
+
+By this time she had found her way into a tidy little room with a table
+in the window, and on it (as she had hoped) a fan and two or three pairs
+of tiny white kid gloves: she took up the fan and a pair of the gloves,
+and was just going to leave the room, when her eye fell upon a little
+bottle that stood near the looking-glass. There was no label this time
+with the words "DRINK ME," but nevertheless she uncorked it and put it
+to her lips. "I know _something_ interesting is sure to happen," she
+said to herself, "whenever I eat or drink anything; so I'll just see
+what this bottle does. I do hope it will make me grow large again, for
+really I'm quite tired of being such a tiny little thing!"
+
+It did so indeed, and much sooner than she had expected: before she had
+drunk half the bottle, she found her head pressing against the ceiling,
+and had to stoop to save her neck from being broken. She hastily put
+down the bottle, saying to herself "That's quite enough--I hope I
+sha'n't grow any more--As it is, I can't get out at the door--I do wish
+I hadn't drunk quite so much!"
+
+Alas! it was too late to wish that! She went on growing, and growing,
+and very soon had to kneel down on the floor: in another minute there
+was not even room for this, and she tried the effect of lying down with
+one elbow against the door, and the other arm curled round her head.
+Still she went on growing, and, as a last resource, she put one arm out
+of the window, and one foot up the chimney, and said to herself "Now I
+can do no more, whatever happens. What _will_ become of me?"
+
+Luckily for Alice, the little magic bottle had now had its full effect,
+and she grew no larger: still it was very uncomfortable, and, as there
+seemed to be no sort of chance of her ever getting out of the room
+again, no wonder she felt unhappy.
+
+"It was much pleasanter at home," thought poor Alice, "when one wasn't
+always growing larger and smaller, and being ordered about by mice and
+rabbits. I almost wish I hadn't gone down that rabbit-hole--and
+yet--and yet--it's rather curious, you know, this sort of life! I do
+wonder what _can_ have happened to me! When I used to read fairy-tales,
+I fancied that kind of thing never happened, and now here I am in the
+middle of one! There ought to be a book written about me, that there
+ought! And when I grow up, I'll write one--but I'm grown up now," she
+added in a sorrowful tone; "at least there's no room to grow up any more
+_here_."
+
+"But then," thought Alice, "shall I _never_ get any older than I am now?
+That'll be a comfort, one way--never to be an old woman--but
+then--always to have lessons to learn! Oh, I shouldn't like _that_!"
+
+"Oh, you foolish Alice!" she answered herself. "How can you learn
+lessons in here? Why, there's hardly room for _you_, and no room at all
+for any lesson-books!"
+
+And so she went on, taking first one side and then the other, and making
+quite a conversation of it altogether; but after a few minutes she heard
+a voice outside, and stopped to listen.
+
+"Mary Ann! Mary Ann!" said the voice. "Fetch me my gloves this moment!"
+Then came a little pattering of feet on the stairs. Alice knew it was
+the Rabbit coming to look for her, and she trembled till she shook the
+house, quite forgetting that she was now about a thousand times as large
+as the Rabbit, and had no reason to be afraid of it.
+
+Presently the Rabbit came up to the door, and tried to open it; but, as
+the door opened inwards, and Alice's elbow was pressed hard against it,
+that attempt proved a failure. Alice heard it say to itself "Then I'll
+go round and get in at the window."
+
+"_That_ you won't" thought Alice, and, after waiting till she fancied
+she heard the Rabbit just under the window, she suddenly spread out her
+hand, and made a snatch in the air. She did not get hold of anything,
+but she heard a little shriek and a fall, and a crash of broken glass,
+from which she concluded that it was just possible it had fallen into a
+cucumber-frame, or something of the sort.
+
+Next came an angry voice--the Rabbit's--"Pat! Pat! Where are you?" And
+then a voice she had never heard before, "Sure then I'm here! Digging
+for apples, yer honour!"
+
+"Digging for apples, indeed!" said the Rabbit angrily. "Here! Come and
+help me out of _this_!" (Sounds of more broken glass.)
+
+"Now tell me, Pat, what's that in the window?"
+
+"Sure, it's an arm, yer honour." (He pronounced it "arrum.")
+
+"An arm, you goose! Who ever saw one that size? Why, it fills the whole
+window!"
+
+"Sure, it does, yer honour? but it's an arm for all that."
+
+"Well, it's got no business there, at any rate: go and take it away!"
+
+There was a long silence after this, and Alice could only hear whispers
+now and then; such as, "Sure, I don't like it, yer honour, at all, at
+all!" "Do as I tell you, you coward!" and at last she spread out her
+hand again, and made another snatch in the air. This time there were
+_two_ little shrieks, and more sounds of broken glass. "What a number of
+cucumber-frames there must be!" thought Alice. "I wonder what they'll do
+next! As for pulling me out of the window, I only wish they _could_!
+I'm sure _I_ don't want to stay in here any longer!"
+
+She waited for some time without hearing anything more: at last came a
+rumbling of little cart-wheels, and the sound of a good many voices all
+talking together: she made out the words: "Where's the other
+ladder?--Why I hadn't to bring but one; Bill's got the other--Bill!
+Fetch it here, lad!--Here, put 'em up at this corner--No, tie 'em
+together first--they don't reach half high enough yet--Oh! they'll do
+well enough; don't be particular--Here, Bill! catch hold of this
+rope--Will the roof bear?--Mind that loose slate--Oh, it's coming down!
+Heads below!" (a loud crash)--"Now, who did that?--It was Bill, I
+fancy--Who's to go down the chimney?--Nay, _I_ sha'n't! _You_ do
+it!--_That_ I won't, then! Bill's to go down--Here, Bill! the master
+says you've to go down the chimney!"
+
+"Oh! So Bill's got to come down the chimney, has he?" said Alice to
+herself. "Why, they seem to put everything upon Bill! I wouldn't be in
+Bill's place for a good deal: this fireplace is narrow, to be sure; but
+I _think_ I can kick a little!"
+
+She drew her foot as far down the chimney as she could, and waited till
+she heard a little animal (she couldn't guess of what sort it was)
+scratching and scrambling about in the chimney close above her: then,
+saying to herself "This is Bill," she gave one sharp kick, and waited to
+see what would happen next.
+
+The first thing she heard was a general chorus of "There goes Bill!"
+then the Rabbit's voice alone--"Catch him, you by the hedge!" then
+silence, and then another confusion of voices--"Hold up his head--Brandy
+now--Don't choke him--How was it, old fellow? What happened to you? Tell
+us all about it!"
+
+At last came a little feeble, squeaking voice, ("That's Bill," thought
+Alice,) "Well, I hardly know--No more, thank ye; I'm better now--but I'm
+a deal too flustered to tell you--all I know is, something comes at me
+like a Jack-in-the-box, and up I goes like a sky-rocket!"
+
+"So you did, old fellow!" said the others.
+
+"We must burn the house down!" said the Rabbit's voice. And Alice
+called out as loud as she could, "If you do, I'll set Dinah at you!"
+
+There was a dead silence instantly, and Alice thought to herself "I
+wonder what they _will_ do next! If they had any sense, they'd take the
+roof off." After a minute or two they began moving about again, and
+Alice heard the Rabbit say "A barrowful will do, to begin with."
+
+"A barrowful of _what_?" thought Alice. But she had not long to doubt,
+for the next moment a shower of little pebbles came rattling in at the
+window, and some of them hit her in the face. "I'll put a stop to this,"
+she said to herself, and shouted out "You'd better not do that again!"
+which produced another dead silence.
+
+Alice noticed with some surprise that the pebbles were all turning into
+little cakes as they lay on the floor, and a bright idea came into her
+head. "If I eat one of these cakes," she thought, "it's sure to make
+_some_ change in my size; and, as it can't possibly make me larger, it
+must make me smaller, I suppose."
+
+So she swallowed one of the cakes, and was delighted to find that she
+began shrinking directly. As soon as she was small enough to get through
+the door, she ran out of the house, and found quite a crowd of little
+animals and birds waiting outside. The poor little Lizard, Bill, was in
+the middle, being held up by two guinea-pigs, who were giving it
+something out of a bottle. They all made a rush at Alice the moment she
+appeared; but she ran off as hard as she could, and soon found herself
+safe in a thick wood.
+
+"The first thing I've got to do," said Alice to herself, as she wandered
+about in the wood, "is to grow to my right size again; and the second
+thing is to find my way into that lovely garden. I think that will be
+the best plan."
+
+It sounded an excellent plan, no doubt, and very neatly and simply
+arranged; the only difficulty was, that she had not the smallest idea
+how to set about it; and, while she was peering about anxiously among
+the trees, a little sharp bark just over her head made her look up in a
+great hurry.
+
+An enormous puppy was looking down at her with large round eyes, and
+feebly stretching out one paw, trying to touch her. "Poor little
+thing!" said Alice, in a coaxing tone, and she tried hard to whistle to
+it; but she was terribly frightened all the time at the thought that it
+might be hungry, in which case it would be very likely to eat her up in
+spite of all her coaxing.
+
+Hardly knowing what she did, she picked up a little bit of stick, and
+held it out to the puppy; whereupon the puppy jumped into the air off
+all its feet at once, with a yelp of delight, and rushed at the stick,
+and made believe to worry it; then Alice dodged behind a great thistle,
+to keep herself from being run over; and, the moment she appeared on the
+other side, the puppy made another rush at the stick, and tumbled head
+over heels in its hurry to get hold of it; then Alice, thinking it was
+very like having a game of play with a cart-horse, and expecting every
+moment to be trampled under its feet, ran round the thistle again; then
+the puppy began a series of short charges at the stick, running a little
+way forwards each time and a long way back, and barking hoarsely all the
+while, till at last it sat down a good way off, panting, with its
+tongue hanging out of its mouth, and its great eyes half shut.
+
+This seemed to Alice a good opportunity for making her escape; so she
+set off at once, and ran till she was quite tired and out of breath, and
+till the puppy's bark sounded quite faint in the distance.
+
+"And yet what a dear little puppy it was!" said Alice, as she leant
+against a buttercup to rest herself, and fanned herself with one of the
+leaves. "I should have liked teaching it tricks very much, if--if I'd
+only been the right size to do it! Oh, dear! I'd nearly forgotten that
+I've got to grow up again! Let me see--how _is_ it to be managed? I
+suppose I ought to eat or drink something or other; but the great
+question is, what?"
+
+The great question certainly was, what? Alice looked all round her at
+the flowers and the blades of grass, but she could not see anything that
+looked like the right thing to eat or drink under the circumstances.
+There was a large mushroom growing near her, about the same height as
+herself; and, when she had looked under it, and on both sides of it, and
+behind it, it occurred to her that she might as well look and see what
+was on the top of it.
+
+She stretched herself up on tiptoe, and peeped over the edge of the
+mushroom, and her eyes immediately met those of a large blue
+caterpillar, that was sitting on the top with its arms folded, quietly
+smoking a long hookah, and taking not the smallest notice of her or of
+anything else.
+
+
+
+
+CHAPTER V
+
+
+[Sidenote: _Advice from a Caterpillar_]
+
+THE Caterpillar and Alice looked at each other for some
+time in silence: at last the Caterpillar took the hookah out of its
+mouth, and addressed her in a languid, sleepy voice.
+
+"Who are _you_?" said the Caterpillar.
+
+This was not an encouraging opening for a conversation. Alice replied,
+rather shyly, "I hardly know, sir, just at present--at least I know who
+I _was_ when I got up this morning, but I think I must have been changed
+several times since then."
+
+"What do you mean by that?" said the Caterpillar sternly. "Explain
+yourself!"
+
+"I can't explain _myself_, I'm afraid, sir," said Alice, "because I'm
+not myself, you see."
+
+"I don't see," said the Caterpillar.
+
+"I'm afraid I can't put it more clearly," Alice replied very politely,
+"for I can't understand it myself to begin with; and being so many
+different sizes in a day is very confusing."
+
+"It isn't," said the Caterpillar.
+
+"Well, perhaps you haven't found it so yet," said Alice, "but when you
+have to turn into a chrysalis--you will some day, you know--and then
+after that into a butterfly, I should think you'll feel it a little
+queer, won't you?"
+
+"Not a bit," said the Caterpillar.
+
+"Well, perhaps your feelings may be different," said Alice; "all I know
+is, it would feel very queer to _me_."
+
+"You!" said the Caterpillar contemptuously. "Who are _you_?"
+
+Which brought them back again to the beginning of the conversation.
+Alice felt a little irritated at the Caterpillar's making such _very_
+short remarks, and she drew herself up and said, very gravely, "I think
+you ought to tell me who _you_ are, first."
+
+"Why?" said the Caterpillar.
+
+[Illustration: _Advice from a Caterpillar_]
+
+Here was another puzzling question; and as Alice could not think of any
+good reason, and as the Caterpillar seemed to be in a _very_
+unpleasant state of mind, she turned away.
+
+"Come back!" the Caterpillar called after her. "I've something important
+to say!"
+
+This sounded promising, certainly: Alice turned and came back again.
+
+"Keep your temper," said the Caterpillar.
+
+"Is that all?" said Alice, swallowing down her anger as well as she
+could.
+
+"No," said the Caterpillar.
+
+Alice thought she might as well wait, as she had nothing else to do, and
+perhaps after all it might tell her something worth hearing. For some
+minutes it puffed away without speaking, but at last it unfolded its
+arms, took the hookah out of its mouth again, and said, "So you think
+you're changed, do you?"
+
+"I'm afraid I am, sir," said Alice; "I can't remember things as I
+used--and I don't keep the same size for ten minutes together!"
+
+"Can't remember _what_ things?" said the Caterpillar.
+
+"Well, I've tried to say '_How doth the little busy bee_,' but it all
+came different!" Alice replied in a very melancholy voice.
+
+"Repeat '_You are old, Father William_,'" said the Caterpillar.
+
+Alice folded her hands, and began:--
+
+ "You are old, Father William," the young man said,
+ "And your hair has become very white;
+ And yet you incessantly stand on your head--
+ Do you think, at your age, it is right?"
+
+ "In my youth," Father William replied to his son,
+ "I feared it might injure the brain;
+ But, now that I'm perfectly sure I have none,
+ Why, I do it again and again."
+
+ "You are old," said the youth, "as I mentioned before,
+ And have grown most uncommonly fat;
+ Yet you turned a back-somersault in at the door--
+ Pray, what is the reason of that?"
+
+ "In my youth," said the sage, as he shook his grey locks,
+ "I kept all my limbs very supple
+ By the use of this ointment--one shilling the box--
+ Allow me to sell you a couple?"
+
+ "You are old," said the youth, "and your jaws are too weak
+ For anything tougher than suet;
+ Yet you finished the goose, with the bones and the beak--
+ Pray, how did you manage to do it?"
+
+ "In my youth," said his father, "I took to the law
+ And argued each case with my wife;
+ And the muscular strength, which it gave to my jaw,
+ Has lasted the rest of my life."
+
+ "You are old," said the youth, "one would hardly suppose
+ That your eye was as steady as ever;
+ Yet you balanced an eel on the end of your nose--
+ What made you so awfully clever?"
+
+ "I have answered three questions, and that is enough,"
+ Said his father; "don't give yourself airs!
+ Do you think I can listen all day to such stuff?
+ Be off, or I'll kick you down stairs!"
+
+"That is not said right," said the Caterpillar.
+
+"Not _quite_ right, I'm afraid," said Alice, timidly; "some of the
+words have got altered."
+
+"It is wrong from beginning to end," said the Caterpillar, decidedly,
+and there was silence for some minutes.
+
+The Caterpillar was the first to speak.
+
+"What size do you want to be?" it asked.
+
+"Oh, I'm not particular as to size," Alice hastily replied; "only one
+doesn't like changing so often, you know."
+
+"I _don't_ know," said the Caterpillar.
+
+Alice said nothing: she had never been so much contradicted in all her
+life before, and she felt that she was losing her temper.
+
+"Are you content now?" said the Caterpillar.
+
+"Well, I should like to be a _little_ larger, sir, if you wouldn't
+mind," said Alice: "three inches is such a wretched height to be."
+
+"It is a very good height indeed!" said the Caterpillar angrily, rearing
+itself upright as it spoke (it was exactly three inches high).
+
+"But I'm not used to it!" pleaded poor Alice in a piteous tone. And she
+thought to herself, "I wish the creatures wouldn't be so easily
+offended!"
+
+"You'll get used to it in time," said the Caterpillar; and it put its
+hookah into its mouth and began smoking again.
+
+This time Alice waited patiently until it chose to speak again. In a
+minute or two the Caterpillar took the hookah out of its mouth and
+yawned once or twice, and shook itself. Then it got down off the
+mushroom, and crawled away into the grass, merely remarking as it went,
+"One side will make you grow taller, and the other side will make you
+grow shorter."
+
+"One side of _what_? The other side of _what_?" thought Alice to
+herself.
+
+"Of the mushroom," said the Caterpillar, just as if she had asked it
+aloud; and in another moment it was out of sight.
+
+Alice remained looking thoughtfully at the mushroom for a minute, trying
+to make out which were the two sides of it; and as it was perfectly
+round, she found this a very difficult question. However, at last she
+stretched her arms round it as far as they would go, and broke off a bit
+of the edge with each hand.
+
+"And now which is which?" she said to herself, and nibbled a little of
+the right-hand bit to try the effect: the next moment she felt a violent
+blow underneath her chin: it had struck her foot!
+
+[Illustration]
+
+She was a good deal frightened by this very sudden change, but she felt
+that there was no time to be lost, as she was shrinking rapidly; so she
+set to work at once to eat some of the other bit. Her chin was pressed
+so closely against her foot that there was hardly room to open her
+mouth; but she did it at last, and managed to swallow a morsel of the
+left-hand bit.
+
+ * * * * *
+
+"Come, my head's free at last!" said Alice in a tone of delight, which
+changed into alarm in another moment, when she found that her shoulders
+were nowhere to be found: all she could see, when she looked down, was
+an immense length of neck, which seemed to rise like a stalk out of a
+sea of green leaves that lay far below her.
+
+"What _can_ all that green stuff be?" said Alice. "And where have my
+shoulders got to? And oh, my poor hands, how is it I ca'n't see you?"
+She was moving them about as she spoke, but no result seemed to follow,
+except a little shaking among the distant green leaves.
+
+As there seemed to be no chance of getting her hands up to her head, she
+tried to get her head down to them, and was delighted to find that her
+neck would bend about easily in any direction, like a serpent. She had
+just succeeded in curving it down into a graceful zigzag, and was going
+to dive in among the leaves, which she found to be nothing but the tops
+of the trees under which she had been wandering, when a sharp hiss made
+her draw back in a hurry: a large pigeon had flown into her face, and
+was beating her violently with its wings.
+
+"Serpent!" screamed the Pigeon.
+
+"I'm _not_ a serpent!" said Alice indignantly. "Let me alone!"
+
+"Serpent, I say again!" repeated the Pigeon, but in a more subdued tone,
+and added with a kind of a sob, "I've tried every way, and nothing seems
+to suit them!"
+
+"I haven't the least idea what you're talking about," said Alice.
+
+"I've tried the roots of trees, and I've tried banks, and I've tried
+hedges," the Pigeon went on, without attending to her; "but those
+serpents! There's no pleasing them!"
+
+Alice was more and more puzzled, but she thought there was no use in
+saying anything more till the Pigeon had finished.
+
+"As if it wasn't trouble enough hatching the eggs," said the Pigeon;
+"but I must be on the look-out for serpents night and day! Why, I
+haven't had a wink of sleep these three weeks!"
+
+"I'm very sorry you've been annoyed," said Alice, who was beginning to
+see its meaning.
+
+[Illustration]
+
+"And just as I'd taken the highest tree in the wood," continued the
+Pigeon, raising its voice to a shriek, "and just as I was thinking I
+should be free of them at last, they must needs come wriggling down from
+the sky! Ugh, Serpent!"
+
+"But I'm _not_ a serpent, I tell you!" said Alice. "I'm a---- I'm a
+----"
+
+"Well! _What_ are you?" said the Pigeon. "I can see you're trying to
+invent something!"
+
+"I--I'm a little girl," said Alice, rather doubtfully, as she remembered
+the number of changes she had gone through that day.
+
+"A likely story indeed!" said the Pigeon in a tone of the deepest
+contempt. "I've seen a good many little girls in my time, but never
+_one_ with such a neck as that! No, no! You're a serpent; and there's no
+use denying it. I suppose you'll be telling me next that you never
+tasted an egg!"
+
+"I _have_ tasted eggs, certainly," said Alice, who was a very truthful
+child; "but little girls eat eggs quite as much as serpents do, you
+know."
+
+"I don't believe it," said the Pigeon; "but if they do, why then
+they're a kind of serpent, that's all I can say."
+
+This was such a new idea to Alice, that she was quite silent for a
+minute or two, which gave the Pigeon the opportunity of adding, "You're
+looking for eggs, I know _that_ well enough; and what does it matter to
+me whether you're a little girl or a serpent?"
+
+"It matters a good deal to _me_," said Alice hastily; "but I'm not
+looking for eggs, as it happens; and if I was, I shouldn't want _yours_:
+I don't like them raw."
+
+"Well, be off, then!" said the Pigeon in a sulky tone, as it settled
+down again into its nest. Alice crouched down among the trees as well as
+she could, for her neck kept getting entangled among the branches, and
+every now and then she had to stop and untwist it. After a while she
+remembered that she still held the pieces of mushroom in her hands, and
+she set to work very carefully, nibbling first at one and then at the
+other, and growing sometimes taller and sometimes shorter, until she had
+succeeded in bringing herself down to her usual height.
+
+It was so long since she had been anything near the right size, that it
+felt quite strange at first; but she got used to it in a few minutes,
+and began talking to herself, as usual. "Come, there's half my plan done
+now! How puzzling all these changes are! I'm never sure what I'm going
+to be, from one minute to another! However, I've got back to my right
+size: the next thing is, to get into that beautiful garden--how _is_
+that to be done, I wonder?" As she said this, she came suddenly upon an
+open place, with a little house in it about four feet high. "Whoever
+lives there," thought Alice, "it'll never do to come upon them _this_
+size: why, I should frighten them out of their wits!" So she began
+nibbling at the right-hand bit again, and did not venture to go near the
+house till she had brought herself down to nine inches high.
+
+
+
+
+CHAPTER VI
+
+
+[Sidenote: _Pig and Pepper_]
+
+FOR a minute or two she stood looking at the house, and
+wondering what to do next, when suddenly a footman in livery came
+running out of the wood--(she considered him to be a footman because he
+was in livery: otherwise, judging by his face only, she would have
+called him a fish)--and rapped loudly at the door with his knuckles. It
+was opened by another footman in livery, with a round face and large
+eyes like a frog; and both footmen, Alice noticed, had powdered hair
+that curled all over their heads. She felt very curious to know what it
+was all about, and crept a little way out of the wood to listen.
+
+The Fish-Footman began by producing from under his arm a great letter,
+nearly as large as himself, and this he handed over to the other,
+saying, in a solemn tone, "For the Duchess. An invitation from the
+Queen to play croquet." The Frog-Footman repeated, in the same solemn
+tone, only changing the order of the words a little, "From the Queen. An
+invitation for the Duchess to play croquet."
+
+Then they both bowed low, and their curls got entangled together.
+
+Alice laughed so much at this, that she had to run back into the wood
+for fear of their hearing her; and, when she next peeped out, the
+Fish-Footman was gone, and the other was sitting on the ground near the
+door, staring stupidly up into the sky.
+
+Alice went timidly up to the door and knocked.
+
+"There's no use in knocking," said the Footman, "and that for two
+reasons. First, because I'm on the same side of the door as you are;
+secondly, because they're making such a noise inside, no one could
+possibly hear you." And certainly there was a most extraordinary noise
+going on within--a constant howling and sneezing, and every now and then
+a great crash, as if a dish or kettle had been broken to pieces.
+
+"Please, then," said Alice, "how am I to get in?"
+
+"There might be some sense in your knocking," the Footman went on
+without attending to her, "if we had the door between us. For instance,
+if you were _inside_, you might knock, and I could let you out, you
+know." He was looking up into the sky all the time he was speaking, and
+this Alice thought decidedly uncivil. "But perhaps he can't help it,"
+she said to herself: "his eyes are so _very_ nearly at the top of his
+head. But at any rate he might answer questions. How am I to get in?"
+she repeated aloud.
+
+"I shall sit here," the Footman remarked, "till to-morrow----"
+
+At this moment the door of the house opened, and a large plate came
+skimming out, straight at the Footman's head: it just grazed his nose,
+and broke to pieces against one of the trees behind him.
+
+"----or next day, maybe," the Footman continued in the same tone,
+exactly as if nothing had happened.
+
+"How am I to get in?" asked Alice again in a louder tone.
+
+"_Are_ you to get in at all?" said the Footman. "That's the first
+question, you know."
+
+[Illustration]
+
+It was, no doubt: only Alice did not like to be told so. "It's really
+dreadful," she muttered to herself, "the way all the creatures argue.
+It's enough to drive one crazy!"
+
+The Footman seemed to consider this a good opportunity for repeating his
+remark, with variations. "I shall sit here," he said, "on and off, for
+days and days."
+
+"But what am _I_ to do?" said Alice.
+
+"Anything you like," said the Footman, and began whistling.
+
+"Oh, there's no use in talking to him," said Alice desperately: "he's
+perfectly idiotic!" And she opened the door and went in.
+
+The door led right into a large kitchen, which was full of smoke from
+one end to the other: the Duchess was sitting on a three-legged stool in
+the middle, nursing a baby, the cook was leaning over the fire, stirring
+a large cauldron which seemed to be full of soup.
+
+"There's certainly too much pepper in that soup!" Alice said to herself,
+as well as she could for sneezing.
+
+There was certainly too much of it in the air. Even the Duchess sneezed
+occasionally; and the baby was sneezing and howling alternately without
+a moment's pause. The only things in the kitchen that did not sneeze,
+were the cook, and a large cat which was sitting on the hearth and
+grinning from ear to ear.
+
+"Please would you tell me," said Alice a little timidly, for she was not
+quite sure whether it was good manners for her to speak first, "why your
+cat grins like that?"
+
+"It's a Cheshire cat," said the Duchess, "and that's why. Pig!"
+
+She said the last word with such sudden violence that Alice quite
+jumped; but she saw in another moment that it was addressed to the baby,
+and not to her, so she took courage, and went on again:
+
+"I didn't know that Cheshire cats always grinned; in fact, I didn't know
+that cats _could_ grin."
+
+"They all can," said the Duchess; "and most of 'em do."
+
+"I don't know of any that do," Alice said very politely, feeling quite
+pleased to have got into a conversation.
+
+"You don't know much," said the Duchess; "and that's a fact."
+
+Alice did not at all like the tone of this remark, and thought it would
+be as well to introduce some other subject of conversation. While she
+was trying to fix on one, the cook took the cauldron of soup off the
+fire, and at once set to work throwing everything within her reach at
+the Duchess and the baby--the fire-irons came first; then followed a
+shower of saucepans, plates, and dishes. The Duchess took no notice of
+them even when they hit her; and the baby was howling so much already,
+that it was quite impossible to say whether the blows hurt it or not.
+
+"Oh, _please_ mind what you're doing!" cried Alice, jumping up and down
+in an agony of terror. "Oh, there goes his _precious_ nose"; as an
+unusually large saucepan flew close by it, and very nearly carried it
+off.
+
+"If everybody minded their own business," the Duchess said in a hoarse
+growl, "the world would go round a deal faster than it does."
+
+[Illustration: _An unusually large saucepan flew close by it, and very
+nearly carried it off_]
+
+"Which would _not_ be an advantage," said Alice, who felt very glad to
+get an opportunity of showing off a little of her knowledge. "Just think
+what work it would make with the day and night! You see the earth
+takes twenty-four hours to turn round on its axis----"
+
+"Talking of axes," said the Duchess, "chop off her head."
+
+Alice glanced rather anxiously at the cook, to see if she meant to take
+the hint; but the cook was busily engaged in stirring the soup, and did
+not seem to be listening, so she ventured to go on again: "Twenty-four
+hours, I _think_; or is it twelve? I----"
+
+"Oh, don't bother _me_," said the Duchess; "I never could abide
+figures!" And with that she began nursing her child again, singing a
+sort of lullaby to it as she did so, and giving it a violent shake at
+the end of every line:
+
+ "Speak roughly to your little boy,
+ And beat him when he sneezes:
+ He only does it to annoy,
+ Because he knows it teases."
+
+CHORUS
+
+ (In which the cook and the baby joined):
+ "Wow! wow! wow!"
+
+While the Duchess sang the second verse of the song, she kept tossing
+the baby violently up and down, and the poor little thing howled so,
+that Alice could hardly hear the words:
+
+ "I speak severely to my boy,
+ I beat him when he sneezes;
+ For he can thoroughly enjoy
+ The pepper when he pleases!"
+
+ CHORUS.
+
+ "Wow! wow! wow!"
+
+"Here! you may nurse it a bit if you like!" the Duchess said to Alice,
+flinging the baby at her as she spoke. "I must go and get ready to play
+croquet with the Queen," and she hurried out of the room. The cook threw
+a frying-pan after her as she went out, but it just missed her.
+
+Alice caught the baby with some difficulty, as it was a queer-shaped
+little creature, and held out its arms and legs in all directions, "just
+like a star-fish," thought Alice. The poor little thing was snorting
+like a steam-engine when she caught it, and kept doubling itself up and
+straightening itself out again, so that altogether, for the first minute
+or two, it was as much as she could do to hold it.
+
+As soon as she had made out the proper way of nursing it, (which was to
+twist it up into a knot, and then keep tight hold of its right ear and
+left foot, so as to prevent its undoing itself,) she carried it out into
+the open air. "If I don't take this child away with me," thought Alice,
+"they're sure to kill it in a day or two: wouldn't it be murder to leave
+it behind?" She said the last words out loud, and the little thing
+grunted in reply (it had left off sneezing by this time). "Don't grunt,"
+said Alice; "that's not at all a proper way of expressing yourself."
+
+The baby grunted again, and Alice looked very anxiously into its face to
+see what was the matter with it. There could be no doubt that it had a
+_very_ turn-up nose, much more like a snout than a real nose; also its
+eyes were getting extremely small for a baby: altogether Alice did not
+like the look of the thing at all. "But perhaps it was only sobbing,"
+she thought, and looked into its eyes again, to see if there were any
+tears.
+
+No, there were no tears. "If you're going to turn into a pig, my dear,"
+said Alice, seriously, "I'll have nothing more to do with you. Mind
+now!" The poor little thing sobbed again (or grunted, it was impossible
+to say which), and they went on for some while in silence.
+
+Alice was just beginning to think to herself, "Now, what am I to do with
+this creature when I get it home?" when it grunted again, so violently,
+that she looked down into its face in some alarm. This time there could
+be _no_ mistake about it: it was neither more nor less than a pig, and
+she felt that it would be quite absurd for her to carry it any further.
+
+So she set the little creature down, and felt quite relieved to see it
+trot quietly away into the wood. "If it had grown up," she said to
+herself, "it would have made a dreadfully ugly child: but it makes
+rather a handsome pig, I think." And she began thinking over other
+children she knew, who might do very well as pigs, and was just saying
+to herself, "if one only knew the right way to change them----" when she
+was a little startled by seeing the Cheshire Cat sitting on a bough of a
+tree a few yards off.
+
+[Illustration: _It grunted again so violently that she looked down into
+its face in some alarm_]
+
+The Cat only grinned when it saw Alice. It looked good-natured, she
+thought: still it had _very_ long claws and a great many teeth, so she
+felt that it ought to be treated with respect.
+
+[Illustration]
+
+"Cheshire Puss," she began, rather timidly, as she did not at all know
+whether it would like the name: however, it only grinned a little wider.
+"Come, it's pleased so far," thought Alice, and she went on. "Would you
+tell me, please, which way I ought to go from here?"
+
+"That depends a good deal on where you want to get to," said the Cat.
+
+"I don't much care where----" said Alice.
+
+"Then it doesn't matter which way you go," said the Cat.
+
+"---- so long as I get _somewhere_," Alice added as an explanation.
+
+"Oh, you're sure to do that," said the Cat, "if you only walk long
+enough."
+
+Alice felt that this could not be denied, so she tried another question.
+"What sort of people live about here?"
+
+"In _that_ direction," the Cat said, waving its right paw round, "lives
+a Hatter: and in _that_ direction," waving the other paw, "lives a March
+Hare. Visit either you like: they're both mad."
+
+"But I don't want to go among mad people," Alice remarked.
+
+"Oh, you ca'n't help that," said the Cat: "we're all mad here. I'm mad.
+You're mad."
+
+"How do you know I'm mad?" said Alice.
+
+"You must be," said the Cat, "or you wouldn't have come here."
+
+Alice didn't think that proved it at all; however, she went on. "And how
+do you know that you're mad?"
+
+"To begin with," said the Cat, "a dog's not mad. You grant that?"
+
+"I suppose so," said Alice.
+
+"Well, then," the Cat went on, "you see a dog growls when it's angry,
+and wags its tail when it's pleased. Now _I_ growl when I'm pleased, and
+wag my tail when I'm angry. Therefore I'm mad."
+
+"_I_ call it purring, not growling," said Alice.
+
+"Call it what you like," said the Cat. "Do you play croquet with the
+Queen to-day?"
+
+"I should like it very much," said Alice, "but I haven't been invited
+yet."
+
+"You'll see me there," said the Cat and vanished.
+
+Alice was not much surprised at this, she was getting so used to queer
+things happening. While she was looking at the place where it had been,
+it suddenly appeared again.
+
+"By-the-bye, what became of the baby?" said the Cat. "I'd nearly
+forgotten to ask."
+
+"It turned into a pig," Alice quietly said, just as if it had come back
+in a natural way.
+
+"I thought it would," said the Cat, and vanished again.
+
+Alice waited a little, half expecting to see it again, but it did not
+appear, and after a minute or two she walked on in the direction in
+which the March Hare was said to live. "I've seen hatters before," she
+said to herself; "the March Hare will be much the most interesting, and
+perhaps as this is May, it won't be raving mad--at least not so mad as
+it was in March." As she said this, she looked up, and there was the Cat
+again, sitting on the branch of a tree.
+
+"Did you say pig, or fig?" said the Cat.
+
+"I said pig," replied Alice; "and I wish you wouldn't keep appearing and
+vanishing so suddenly: you make one quite giddy."
+
+"All right," said the Cat; and this time it vanished quite slowly,
+beginning with the end of the tail, and ending with the grin, which
+remained some time after the rest of it had gone.
+
+"Well! I've often seen a cat without a grin," thought Alice; "but a grin
+without a cat! It's the most curious thing I ever saw in all my life."
+
+[Illustration]
+
+She had not gone much farther before she came in sight of the house of
+the March Hare: she thought it must be the right house, because the
+chimneys were shaped like ears and the roof was thatched with fur. It
+was so large a house, that she did not like to go nearer till she had
+nibbled some more of the left-hand bit of mushroom, and raised herself,
+to about two feet high: even then she walked up towards it rather
+timidly, saying to herself, "Suppose it should be raving mad after all!
+I almost wish I'd gone to see the Hatter instead!"
+
+
+
+
+CHAPTER VII
+
+
+[Sidenote: _A Mad Tea-party_]
+
+THERE was a table set out under a tree in front of the
+house, and the March Hare and the Hatter were having tea at it: a
+Dormouse was sitting between them, fast asleep, and the other two were
+using it as a cushion resting their elbows on it, and talking over its
+head. "Very uncomfortable for the Dormouse," thought Alice; "only as
+it's asleep, suppose it doesn't mind."
+
+The table was a large one, but the three were all crowded together at
+one corner of it. "No room! No room!" they cried out when they saw Alice
+coming. "There's _plenty_ of room!" said Alice indignantly, and she sat
+down in a large arm-chair at one end of the table.
+
+"Have some wine," the March Hare said in an encouraging tone.
+
+Alice looked all round the table, but there was nothing on it but tea.
+"I don't see any wine," she remarked.
+
+"There isn't any," said the March Hare.
+
+"Then it wasn't very civil of you to offer it," said Alice angrily.
+
+"It wasn't very civil of you to sit down without being invited," said
+the March Hare.
+
+"I didn't know it was _your_ table," said Alice; "it's laid for a great
+many more than three."
+
+"Your hair wants cutting," said the Hatter. He had been looking at Alice
+for some time with great curiosity, and this was his first speech.
+
+"You should learn not to make personal remarks," Alice said with some
+severity; "it's very rude."
+
+The Hatter opened his eyes very wide on hearing this; but all he _said_
+was "Why is a raven like a writing-desk?"
+
+"Come, we shall have some fun now!" thought Alice. "I'm glad they've
+begun asking riddles.--I believe I can guess that," she added aloud.
+
+"Do you mean that you think you can find out the answer to it?" said
+the March Hare.
+
+"Exactly so," said Alice.
+
+"Then you should say what you mean," the March Hare went on.
+
+"I do," Alice hastily replied; "at least--at least I mean what I
+say--that's the same thing, you know."
+
+"Not the same thing a bit!" said the Hatter. "Why, you might just as
+well say that 'I see what I eat' is the same thing as 'I eat what I
+see'!"
+
+"You might just as well say," added the March Hare, "that 'I like what I
+get' is the same thing as 'I get what I like'!"
+
+"You might just as well say," added the Dormouse, which seemed to be
+talking in his sleep, "that 'I breathe when I sleep' is the same thing
+as 'I sleep when I breathe'!"
+
+"It _is_ the same thing with you," said the Hatter; and here the
+conversation dropped, and the party sat silent for a minute, while Alice
+thought over all she could remember about ravens and writing-desks,
+which wasn't much.
+
+[Illustration: _A Mad Tea Party_]
+
+The Hatter was the first to break the silence. "What day of the month
+is it?" he said, turning to Alice: he had taken his watch out of his
+pocket, and was looking at it uneasily, shaking it every now and then,
+and holding it to his ear.
+
+Alice considered a little, and then said "The fourth."
+
+"Two days wrong!" sighed the Hatter. "I told you butter would not suit
+the works!" he added, looking angrily at the March Hare.
+
+"It was the _best_ butter," the March Hare meekly replied.
+
+"Yes, but some crumbs must have got in as well," the Hatter grumbled:
+"you shouldn't have put it in with the bread-knife."
+
+The March Hare took the watch and looked at it gloomily: then he dipped
+it into his cup of tea, and looked at it again: but he could think of
+nothing better to say than his first remark, "It was the _best_ butter,
+you know."
+
+Alice had been looking over his shoulder with some curiosity. "What a
+funny watch!" she remarked. "It tells the day of the month, and doesn't
+tell what o'clock it is!"
+
+"Why should it?" muttered the Hatter. "Does _your_ watch tell you what
+year it is?"
+
+"Of course not," Alice replied very readily: "but that's because it
+stays the same year for such a long time together."
+
+"Which is just the case with _mine_," said the Hatter.
+
+Alice felt dreadfully puzzled. The Hatter's remark seemed to have no
+meaning in it, and yet it was certainly English. "I don't quite
+understand," she said, as politely as she could.
+
+"The Dormouse is asleep again," said the Hatter, and he poured a little
+hot tea upon its nose.
+
+The Dormouse shook its head impatiently, and said, without opening its
+eyes, "Of course, of course; just what I was going to remark myself."
+
+"Have you guessed the riddle yet?" the Hatter said, turning to Alice
+again.
+
+"No, I give it up," Alice replied: "what's the answer?"
+
+"I haven't the slightest idea," said the Hatter.
+
+"Nor I," said the March Hare.
+
+Alice sighed wearily. "I think you might do something better with the
+time," she said, "than wasting it asking riddles with no answers."
+
+"If you knew Time as well as I do," said the Hatter, "you wouldn't talk
+about wasting _it_. It's _him_."
+
+"I don't know what you mean," said Alice.
+
+"Of course you don't!" the Hatter said, tossing his head contemptuously.
+"I daresay you never spoke to Time!"
+
+"Perhaps not," Alice cautiously replied: "but I know I have to beat time
+when I learn music."
+
+"Ah! that accounts for it," said the Hatter. "He won't stand beating.
+Now, if you only kept on good terms with him, he'd do almost anything
+you liked with the clock. For instance, suppose it were nine o'clock in
+the morning, just time to begin lessons: you'd only have to whisper a
+hint to Time, and round goes the clock in a twinkling! Half-past one,
+time for dinner!"
+
+("I only wish it was," the March Hare said to itself in a whisper.)
+
+"That would be grand, certainly," said Alice thoughtfully: "but then--I
+shouldn't be hungry for it, you know."
+
+"Not at first, perhaps," said the Hatter: "but you could keep it to
+half-past one as long as you liked."
+
+"Is that the way _you_ manage?" Alice asked.
+
+The Hatter shook his head mournfully. "Not I!" he replied. "We
+quarrelled last March----just before _he_ went mad, you know----"
+(pointing with his teaspoon to the March Hare), "it was at the great
+concert given by the Queen of Hearts, and I had to sing
+
+ 'Twinkle, twinkle, little bat!
+ How I wonder what you're at!'
+
+You know that song, perhaps?"
+
+"I've heard something like it," said Alice.
+
+"It goes on, you know," the Hatter continued, "in this way:--
+
+ 'Up above the world you fly,
+ Like a tea-tray in the sky.
+ Twinkle, twinkle----'"
+
+Here the Dormouse shook itself, and began singing in its sleep
+"_Twinkle, twinkle, twinkle, twinkle_----" and went on so long that they
+had to pinch it to make it stop.
+
+"Well, I'd hardly finished the first verse," said the Hatter, "when the
+Queen jumped up and bawled out 'He's murdering the time! Off with his
+head!'"
+
+"How dreadfully savage!" exclaimed Alice.
+
+"And ever since that," the Hatter went on in a mournful tone, "he won't
+do a thing I ask! It's always six o'clock now."
+
+A bright idea came into Alice's head. "Is that the reason so many
+tea-things are put out here?" she asked.
+
+"Yes, that's it," said the Hatter with a sigh: "it's always tea-time,
+and we've no time to wash the things between whiles."
+
+"Then you keep moving round, I suppose?" said Alice.
+
+"Exactly so," said the Hatter: "as the things get used up."
+
+"But what happens when you come to the beginning again?" Alice ventured
+to ask.
+
+"Suppose we change the subject," the March Hare interrupted, yawning.
+"I'm getting tired of this. I vote the young lady tells us a story."
+
+"I'm afraid I don't know one," said Alice, rather alarmed at the
+proposal.
+
+"Then the Dormouse shall!" they both cried. "Wake up, Dormouse!" And
+they pinched it on both sides at once.
+
+The Dormouse slowly opened his eyes. "I wasn't asleep," he said in a
+hoarse, feeble voice: "I heard every word you fellows were saying."
+
+"Tell us a story!" said the March Hare.
+
+"Yes, please do!" pleaded Alice.
+
+"And be quick about it," added the Hatter, "or you'll be asleep again
+before it's done."
+
+"Once upon a time there were three little sisters," the Dormouse began
+in a great hurry; "and their names were Elsie, Lacie, and Tillie; and
+they lived at the bottom of a well----"
+
+"What did they live on?" said Alice, who always took a great interest in
+questions of eating and drinking.
+
+"They lived on treacle," said the Dormouse, after thinking a minute or
+two.
+
+"They couldn't have done that, you know," Alice gently remarked; "they'd
+have been ill."
+
+"So they were," said the Dormouse; "_very_ ill."
+
+Alice tried a little to fancy to herself what such an extraordinary way
+of living would be like, but it puzzled her too much, so she went on:
+"But why did they live at the bottom of a well?"
+
+"Take some more tea," the March Hare said to Alice, very earnestly.
+
+"I've had nothing yet," Alice replied in an offended tone, "so I can't
+take more."
+
+"You mean you can't take _less_," said the Hatter; "it's very easy to
+take _more_ than nothing."
+
+"Nobody asked _your_ opinion," said Alice.
+
+"Who's making personal remarks now?" the Hatter asked triumphantly.
+
+Alice did not quite know what to say to this: so she helped herself to
+some tea and bread-and-butter, and then turned to the Dormouse, and
+repeated her question. "Why did they live at the bottom of a well?"
+
+The Dormouse again took a minute or two to think about it, and then
+said, "It was a treacle-well."
+
+"There's no such thing!" Alice was beginning very angrily, but the
+Hatter and the March Hare went "Sh! sh!" and the Dormouse sulkily
+remarked: "If you can't be civil, you'd better finish the story for
+yourself."
+
+"No, please go on!" Alice said very humbly. "I won't interrupt you
+again. I dare say there may be _one_."
+
+"One, indeed!" said the Dormouse indignantly. However, he consented to
+go on. "And so these three little sisters--they were learning to draw,
+you know----"
+
+"What did they draw?" said Alice, quite forgetting her promise.
+
+"Treacle," said the Dormouse, without considering at all this time.
+
+"I want a clean cup," interrupted the Hatter: "let's all move one place
+on."
+
+He moved as he spoke, and the Dormouse followed him: the March Hare
+moved into the Dormouse's place, and Alice rather unwillingly took the
+place of the March Hare. The Hatter was the only one who got any
+advantage from the change: and Alice was a good deal worse off than
+before, as the March Hare had just upset the milk-jug into his plate.
+
+Alice did not wish to offend the Dormouse again, so she began very
+cautiously: "But I don't understand. Where did they draw the treacle
+from?"
+
+"You can draw water out of a water-well," said the Hatter; "so I should
+think you could draw treacle out of a treacle-well--eh, stupid!"
+
+"But they were _in_ the well," Alice said to the Dormouse, not choosing
+to notice this last remark.
+
+"Of course they were," said the Dormouse; "----well in."
+
+This answer so confused poor Alice that she let the Dormouse go on for
+some time without interrupting it.
+
+"They were learning to draw," the Dormouse went on, yawning and rubbing
+its eyes, for it was getting very sleepy; "and they drew all manner of
+things--everything that begins with an M----"
+
+"Why with an M?" said Alice.
+
+"Why not?" said the March Hare.
+
+Alice was silent.
+
+The Dormouse had closed its eyes by this time, and was going off into a
+dose; but, on being pinched by the Hatter, it woke up again with a
+little shriek, and went on: "----that begins with an M, such as
+mouse-traps, and the moon, and memory, and muchness--you know you say
+things are 'much of a muchness'--did you ever see such a thing as a
+drawing of a muchness?"
+
+"Really, now you ask me," said Alice, very much confused, "I don't
+think----"
+
+"Then you shouldn't talk," said the Hatter.
+
+This piece of rudeness was more than Alice could bear: she got up in
+great disgust and walked off; the Dormouse fell asleep instantly, and
+neither of the others took the least notice of her going, though she
+looked back once or twice, half hoping that they would call after her:
+the last time she saw them, they were trying to put the Dormouse into
+the teapot.
+
+"At any rate I'll never go _there_ again!" said Alice as she picked her
+way through the wood. "It's the stupidest tea-party I ever was at in all
+my life!"
+
+Just as she said this, she noticed that one of the trees had a door
+leading right into it. "That's very curious!" she thought. "But
+everything's curious to-day. I think I may as well go in at once." And
+in she went.
+
+Once more she found herself in the long hall, and close to the little
+glass table. "Now I'll manage better this time," she said to herself,
+and began by taking the little golden key, and unlocking the door that
+led into the garden. Then she set to work nibbling at the mushroom (she
+had kept a piece of it in her pocket) till she was about a foot high:
+then she walked down the little passage: and _then_--she found herself
+at last in the beautiful garden, among the bright flower-beds and the
+cool fountains.
+
+
+
+
+CHAPTER VIII
+
+
+[Sidenote: _The Queen's Croquet-Ground_]
+
+A LARGE rose-tree stood near the entrance of the garden:
+the roses growing on it were white, but there were three gardeners at
+it, busily painting them red. Alice thought this a very curious thing,
+and she went nearer to watch them, and just as she came up to them she
+heard one of them say "Look out now, Five! Don't go splashing paint over
+me like that!"
+
+"I couldn't help it," said Five, in a sulky tone. "Seven jogged my
+elbow."
+
+On which Seven looked up and said, "That's right, Five! Always lay the
+blame on others!"
+
+"_You'd_ better not talk!" said Five. "I heard the Queen say only
+yesterday you deserved to be beheaded!"
+
+"What for?" said the one who had first spoken.
+
+"That's none of _your_ business, Two!" said Seven.
+
+"Yes, it _is_ his business!" said Five. "And I'll tell him--it was for
+bringing the cook tulip-roots instead of onions."
+
+Seven flung down his brush, and had just begun "Well, of all the unjust
+things----" when his eye chanced to fall upon Alice, as she stood
+watching them, and he checked himself suddenly: the others looked round
+also, and all of them bowed low.
+
+"Would you tell me," said Alice, a little timidly, "why you are painting
+those roses?"
+
+Five and Seven said nothing, but looked at Two. Two began in a low
+voice, "Why, the fact is, you see, Miss, this here ought to have been a
+_red_ rose-tree, and we put a white one in by mistake; and if the Queen
+was to find it out, we should all have our heads cut off, you know. So
+you see, Miss, we're doing our best, afore she comes, to----" At this
+moment, Five, who had been anxiously looking across the garden, called
+out "The Queen! The Queen!" and the three gardeners instantly threw
+themselves flat upon their faces. There was a sound of many footsteps,
+and Alice looked round, eager to see the Queen.
+
+First came ten soldiers carrying clubs; these were all shaped like the
+three gardeners, oblong and flat, with their hands and feet at the
+corners: next the ten courtiers; these were ornamented all over with
+diamonds, and walked two and two, as the soldiers did. After these came
+the royal children; there were ten of them, and the little dears came
+jumping merrily along hand in hand, in couples; they were all ornamented
+with hearts. Next came the guests, mostly Kings and Queens, and among
+them Alice recognised the White Rabbit: it was talking in a hurried,
+nervous manner, smiling at everything that was said, and went by without
+noticing her. Then followed the Knave of Hearts, carrying the King's
+crown on a crimson velvet cushion; and last of all this grand
+procession, came THE KING AND QUEEN OF HEARTS.
+
+Alice was rather doubtful whether she ought not to lie down on her face
+like the three gardeners, but she could not remember ever having heard
+of such a rule at processions; "and besides, what would be the use of a
+procession," thought she, "if people had to lie down upon their faces,
+so that they couldn't see it?" So she stood still where she was, and
+waited.
+
+When the procession came opposite to Alice, they all stopped and looked
+at her, and the Queen said severely, "Who is this?" She said it to the
+Knave of Hearts, who only bowed and smiled in reply.
+
+"Idiot!" said the Queen, tossing her head impatiently; and turning to
+Alice, she went on, "What's your name, child?"
+
+"My name is Alice, so please your Majesty," said Alice very politely;
+but she added, to herself, "Why, they're only a pack of cards, after
+all. I needn't be afraid of them!"
+
+"And who are _these_?" said the Queen, pointing to the three gardeners
+who were lying round the rose-tree; for, you see, as they were lying on
+their faces, and the pattern on their backs was the same as the rest of
+the pack, she could not tell whether they were gardeners, or soldiers,
+or courtiers, or three of her own children.
+
+"How should _I_ know?" said Alice, surprised at her own courage. "It's
+no business of _mine_."
+
+The Queen turned crimson with fury, and, after glaring at her for a
+moment like a wild beast, screamed "Off with her head! Off----"
+
+"Nonsense!" said Alice, very loudly and decidedly, and the Queen was
+silent.
+
+The King laid his hand upon her arm, and timidly said "Consider my dear:
+she is only a child!"
+
+The Queen turned angrily away from him, and said to the Knave "Turn them
+over!"
+
+The Knave did so, very carefully, with one foot.
+
+"Get up!" said the Queen, in a shrill, loud voice, and the three
+gardeners instantly jumped up, and began bowing to the King, the Queen,
+the royal children, and everybody else.
+
+"Leave off that!" screamed the Queen. "You make me giddy." And then,
+turning to the rose-tree, she went on, "What _have_ you been doing
+here?"
+
+"May it please your Majesty," said Two, in a very humble tone, going
+down on one knee as he spoke, "we were trying----"
+
+[Illustration: _The Queen turned angrily away from him and said to the
+Knave, "Turn them over"_]
+
+"_I_ see!" said the Queen, who had meanwhile been examining the roses.
+"Off with their heads!" and the procession moved on, three of the
+soldiers remaining behind to execute the unfortunate gardeners, who ran
+to Alice for protection.
+
+"You shan't be beheaded!" said Alice, and she put them into a large
+flower-pot that stood near. The three soldiers wandered about for a
+minute or two, looking for them, and then quietly marched off after the
+others.
+
+"Are their heads off?" shouted the Queen.
+
+"Their heads are gone, if it please your Majesty!" the soldiers shouted
+in reply.
+
+"That's right!" shouted the Queen. "Can you play croquet?"
+
+The soldiers were silent, and looked at Alice, as the question was
+evidently meant for her.
+
+"Yes!" shouted Alice.
+
+"Come on, then!" roared the Queen, and Alice joined the procession,
+wondering very much what would happen next.
+
+"It's--it's a very fine day!" said a timid voice at her side. She was
+walking by the White Rabbit, who was peeping anxiously into her face.
+
+"Very," said Alice: "----where's the Duchess?"
+
+"Hush! Hush!" said the Rabbit in a low hurried tone. He looked anxiously
+over his shoulder as he spoke, and then raised himself upon tiptoe, put
+his mouth close to her ear, and whispered "She's under sentence of
+execution."
+
+"What for?" said Alice.
+
+"Did you say 'What a pity!'?" the Rabbit asked.
+
+"No, I didn't," said Alice: "I don't think it's at all a pity. I said
+'What for?'"
+
+"She boxed the Queen's ears--" the Rabbit began. Alice gave a little
+scream of laughter. "Oh, hush!" the Rabbit whispered in a frightened
+tone. "The Queen will hear you! You see she came rather late, and the
+Queen said----"
+
+"Get to your places!" shouted the Queen in a voice of thunder, and
+people began running about in all directions, tumbling up against each
+other; however, they got settled down in a minute or two, and the game
+began. Alice thought she had never seen such a curious croquet-ground in
+all her life; it was all ridges and furrows; the balls were live
+hedgehogs, the mallets live flamingoes, and the soldiers had to double
+themselves up and to stand upon their hands and feet, to make the
+arches.
+
+[Illustration]
+
+The chief difficulty Alice found at first was in managing her flamingo;
+she succeeded in getting its body tucked away, comfortably enough, under
+her arm, with its legs hanging down, but generally, just as she had got
+its neck nicely straightened out, and was going to give the hedgehog a
+blow with its head, it _would_ twist itself round and look up in her
+face, with such a puzzled expression that she could not help bursting
+out laughing: and when she had got its head down, and was going to
+begin again, it was very provoking to find that the hedgehog had
+unrolled itself and was in the act of crawling away: besides all this,
+there was generally a ridge or a furrow in the way wherever she wanted
+to send the hedgehog to, and, as the doubled-up soldiers were always
+getting up and walking off to other parts of the ground, Alice soon came
+to the conclusion that it was a very difficult game indeed.
+
+The players all played at once without waiting for turns, quarrelling
+all the while, and fighting for the hedgehogs; and in a very short time
+the Queen was in a furious passion, and went stamping about, and
+shouting "Off with his head!" or "Off with her head!" about once in a
+minute.
+
+Alice began to feel very uneasy: to be sure she had not as yet had any
+dispute with the Queen, but she knew that it might happen any minute,
+"and then," thought she, "what would become of me? They're dreadfully
+fond of beheading people here: the great wonder is that there's any one
+left alive!"
+
+She was looking about for some way of escape, and wondering whether she
+could get away without being seen, when she noticed a curious
+appearance in the air: it puzzled her very much at first, but, after
+watching it a minute or two, she made it out to be a grin, and she said
+to herself "It's the Cheshire Cat: now I shall have somebody to talk
+to."
+
+"How are you getting on?" said the Cat, as soon as there was mouth
+enough for it to speak with.
+
+Alice waited till the eyes appeared, and then nodded. "It's no use
+speaking to it," she thought, "till its ears have come, or at least one
+of them." In another minute the whole head appeared, and then Alice put
+down her flamingo, and began an account of the game, feeling very glad
+she had some one to listen to her. The Cat seemed to think that there
+was enough of it now in sight, and no more of it appeared.
+
+"I don't think they play at all fairly," Alice began, in rather a
+complaining tone, "and they all quarrel so dreadfully one can't hear
+oneself speak--and they don't seem to have any rules in particular; at
+least, if there are, nobody attends to them--and you've no idea how
+confusing it is all the things being alive; for instance, there's the
+arch I've got to go through next walking about at the other end of the
+ground--and I should have croqueted the Queen's hedgehog just now, only
+it ran away when it saw mine coming!"
+
+[Illustration]
+
+"How do you like the Queen?" said the Cat in a low voice.
+
+"Not at all," said Alice: "she's so extremely----" Just then she noticed
+that the Queen was close behind her listening: so she went on,
+"----likely to win, that it's hardly worth while finishing the game."
+
+The Queen smiled and passed on.
+
+"Who _are_ you talking to?" said the King, coming up to Alice, and
+looking at the Cat's head with great curiosity.
+
+"It's a friend of mine--a Cheshire Cat," said Alice: "allow me to
+introduce it."
+
+"I don't like the look of it at all," said the King: "however, it may
+kiss my hand if it likes."
+
+"I'd rather not," the Cat remarked.
+
+"Don't be impertinent," said the King, "and don't look at me like that!"
+He got behind Alice as he spoke.
+
+"A cat may look at a king," said Alice. "I've read that in some book,
+but I don't remember where."
+
+"Well, it must be removed," said the King very decidedly, and he called
+to the Queen, who was passing at the moment, "My dear! I wish you would
+have this cat removed!"
+
+The Queen had only one way of settling all difficulties, great or small.
+"Off with his head!" she said, without even looking round.
+
+"I'll fetch the executioner myself," said the King eagerly, and he
+hurried off.
+
+Alice thought she might as well go back and see how the game was going
+on, as she heard the Queen's voice in the distance, screaming with
+passion. She had already heard her sentence three of the players to be
+executed for having missed their turns, and she did not like the look of
+things at all, as the game was in such confusion that she never knew
+whether it was her turn or not. So she went in search of her hedgehog.
+
+The hedgehog was engaged in a fight with another hedgehog, which seemed
+to Alice an excellent opportunity for croqueting one of them with the
+other: the only difficulty was, that her flamingo was gone across to the
+other side of the garden, where Alice could see it trying in a helpless
+sort of way to fly up into one of the trees.
+
+By the time she had caught the flamingo and brought it back, the fight
+was over, and both the hedgehogs were out of sight: "but it doesn't
+matter much," thought Alice, "as all the arches are gone from this side
+of the ground." So she tucked it under her arm, that it might not escape
+again, and went back for a little more conversation with her friend.
+
+When she got back to the Cheshire Cat, she was surprised to find quite a
+large crowd collected round it: there was a dispute going on between the
+executioner, the King, and the Queen, who were all talking at once,
+while all the rest were quite silent, and looked very uncomfortable.
+
+The moment Alice appeared, she was appealed to by all three to settle
+the question, and they repeated their arguments to her, though, as they
+all spoke at once, she found it very hard indeed to make out exactly
+what they said.
+
+[Illustration]
+
+The executioner's argument was, that you couldn't cut off a head unless
+there was a body to cut it off from: that he had never had to do such a
+thing before, and he wasn't going to begin at _his_ time of life.
+
+The King's argument was, that anything that had a head could be
+beheaded, and that you weren't to talk nonsense.
+
+The Queen's argument was, that if something wasn't done about it in less
+than no time, she'd have everybody executed all round. (It was this last
+remark that had made the whole party look so grave and anxious.)
+
+Alice could think of nothing else to say but "It belongs to the Duchess:
+you'd better ask _her_ about it."
+
+"She's in prison," the Queen said to the executioner; "fetch her here."
+And the executioner went off like an arrow.
+
+The Cat's head began fading away the moment he was gone, and by the time
+he had come back with the Duchess, it had entirely disappeared; so the
+King and the executioner ran wildly up and down looking for it, while
+the rest of the party went back to the game.
+
+
+
+
+CHAPTER IX
+
+
+[Sidenote: _The Mock Turtle's Story_]
+
+"YOU can't think how glad I am to see you again, you
+dear old thing!" said the Duchess, as she tucked her arm affectionately
+into Alice's, and they walked off together.
+
+Alice was very glad to find her in such a pleasant temper, and thought
+to herself that perhaps it was only the pepper that had made her so
+savage when they met in the kitchen.
+
+"When _I'm_ a Duchess," she said to herself (not in a very hopeful tone
+though), "I won't have any pepper in my kitchen _at all_. Soup does very
+well without--Maybe it's always pepper that makes people hot-tempered,"
+she went on, very much pleased at having found out a new kind of rule,
+"and vinegar that makes them sour--and camomile that makes them
+bitter--and--barley-sugar and such things that make children
+sweet-tempered. I only wish people knew _that_: then they wouldn't be
+so stingy about it, you know----"
+
+She had quite forgotten the Duchess by this time, and was a little
+startled when she heard her voice close to her ear. "You're thinking
+about something, my dear, and that makes you forget to talk. I can't
+tell you just now what the moral of that is, but I shall remember it in
+a bit."
+
+"Perhaps it hasn't one," Alice ventured to remark.
+
+"Tut, tut, child!" said the Duchess. "Every thing's got a moral, if only
+you can find it." And she squeezed herself up closer to Alice's side as
+she spoke.
+
+Alice did not much like her keeping so close to her: first, because the
+Duchess was _very_ ugly; and secondly, because she was exactly the right
+height to rest her chin on Alice's shoulder, and it was an uncomfortably
+sharp chin. However, she did not like to be rude, so she bore it as well
+as she could. "The game's going on rather better now," she said, by way
+of keeping up the conversation a little.
+
+"'Tis so," said the Duchess: "and the moral of that is--'Oh, 'tis love,
+'tis love, that makes the world go round!'"
+
+"Somebody said," Alice whispered, "that it's done by everybody minding
+their own business!"
+
+"Ah, well! It means much the same thing," said the Duchess, digging her
+sharp little chin into Alice's shoulder as she added, "and the moral of
+_that_ is--'Take care of the sense, and the sounds will take care of
+themselves.'"
+
+"How fond she is of finding morals in things!" Alice thought to herself.
+
+"I dare say you're wondering why I don't put my arm round your waist,"
+the Duchess said after a pause: "the reason is, that I'm doubtful about
+the temper of your flamingo. Shall I try the experiment?"
+
+"He might bite," Alice cautiously replied, not feeling at all anxious to
+have the experiment tried.
+
+"Very true," said the Duchess: "flamingoes and mustard both bite. And
+the moral of that is--'Birds of a feather flock together.'"
+
+"Only mustard isn't a bird," Alice remarked.
+
+"Right, as usual," said the Duchess: "what a clear way you have of
+putting things!"
+
+"It's a mineral, I _think_," said Alice.
+
+"Of course it is," said the Duchess, who seemed ready to agree to
+everything that Alice said: "there's a large mustard-mine near here. And
+the moral of that is--'The more there is of mine, the less there is of
+yours.'"
+
+"Oh, I know!" exclaimed Alice, who had not attended to this last remark.
+"It's a vegetable. It doesn't look like one, but it is."
+
+"I quite agree with you," said the Duchess; "and the moral of that
+is--'Be what you would seem to be'--or if you'd like it put more
+simply--'Never imagine yourself not to be otherwise than what it might
+appear to others that what you were or might have been was not otherwise
+than what you had been would have appeared to them to be otherwise.'"
+
+"I think I should understand that better," Alice said very politely, "if
+I had it written down: but I can't quite follow it as you say it."
+
+"That's nothing to what I could say if I chose," the Duchess replied, in
+a pleased tone.
+
+"Pray don't trouble yourself to say it any longer than that," said
+Alice.
+
+"Oh, don't talk about trouble!" said the Duchess. "I make you a present
+of everything I've said as yet."
+
+"A cheap sort of present!" thought Alice. "I'm glad they don't give
+birthday presents like that!" But she did not venture to say it out
+loud.
+
+"Thinking again?" the Duchess asked with another dig of her sharp little
+chin.
+
+"I've a right to think," said Alice sharply, for she was beginning to
+feel a little worried.
+
+"Just about as much right," said the Duchess, "as pigs have to fly; and
+the m----"
+
+But here, to Alice's great surprise, the Duchess's voice died away, even
+in the middle of her favourite word "moral," and the arm that was linked
+into hers began to tremble. Alice looked up, and there stood the Queen
+in front of them, with her arms folded, frowning like a thunderstorm.
+
+"A fine day, your Majesty!" the Duchess began in a low, weak voice.
+
+"Now, I give you fair warning," shouted the Queen, stamping on the
+ground as she spoke; "either you or your head must be off, and that in
+about half no time! Take your choice!"
+
+The Duchess took her choice, and was gone in a moment.
+
+"Let's go on with the game," the Queen said to Alice; and Alice was too
+much frightened to say a word, but slowly followed her back to the
+croquet-ground.
+
+The other guests had taken advantage of the Queen's absence, and were
+resting in the shade: however, the moment they saw her, they hurried
+back to the game, the Queen merely remarking that a moment's delay would
+cost them their lives.
+
+[Illustration: _The Queen never left off quarrelling with the other
+players, and shouting "Off with his head!" or, "Off with her head!"_]
+
+All the time they were playing the Queen never left off quarrelling with
+the other players, and shouting "Off with his head!" or "Off with her
+head!" Those whom she sentenced were taken into custody by the soldiers,
+who of course had to leave off being arches to do this, so that by the
+end of half an hour or so there were no arches left, and all the
+players, except the King, the Queen, and Alice, were in custody and
+under sentence of execution.
+
+Then the Queen left off, quite out of breath, and said to Alice, "Have
+you seen the Mock Turtle yet?"
+
+"No," said Alice. "I don't even know what a Mock Turtle is."
+
+"It's the thing Mock Turtle Soup is made from," said the Queen.
+
+"I never saw one, or heard of one," said Alice.
+
+"Come on then," said the Queen, "and he shall tell you his history."
+
+As they walked off together, Alice heard the King say in a low voice, to
+the company generally, "You are all pardoned." "Come, _that's_ a good
+thing!" she said to herself, for she had felt quite unhappy at the
+number of executions the Queen had ordered.
+
+They very soon came upon a Gryphon, lying fast asleep in the sun. (If
+you don't know what a Gryphon is, look at the picture.) "Up, lazy
+thing!" said the Queen, "and take this young lady to see the Mock
+Turtle, and to hear his history. I must go back and see after some
+executions I have ordered," and she walked off, leaving Alice alone
+with the Gryphon. Alice did not quite like the look of the creature, but
+on the whole she thought it would be quite as safe to stay with it as to
+go after that savage Queen: so she waited.
+
+The Gryphon sat up and rubbed its eyes: then it watched the Queen till
+she was out of sight: then it chuckled. "What fun!" said the Gryphon,
+half to itself, half to Alice.
+
+"What _is_ the fun?" said Alice.
+
+"Why, _she_," said the Gryphon. "It's all her fancy, that: they never
+executes nobody, you know. Come on!"
+
+"Everybody says 'come on!' here," thought Alice, as she went slowly
+after it: "I never was so ordered about in my life, never!"
+
+[Illustration]
+
+They had not gone far before they saw the Mock Turtle in the distance,
+sitting sad and lonely on a little ledge of rock, and, as they came
+nearer, Alice could hear him sighing as if his heart would break. She
+pitied him deeply. "What is his sorrow?" she asked the Gryphon, and the
+Gryphon answered, very nearly in the same words as before, "It's all
+his fancy, that: he hasn't got no sorrow, you know. Come on!"
+
+So they went up to the Mock Turtle, who looked at them with large eyes
+full of tears, but said nothing.
+
+"This here young lady," said the Gryphon, "she wants to know your
+history, she do."
+
+"I'll tell it her," said the Mock Turtle in a deep, hollow tone; "sit
+down, both of you, and don't speak a word till I've finished."
+
+So they sat down, and nobody spoke for some minutes. Alice thought to
+herself, "I don't see how he can _ever_ finish, if he doesn't begin."
+But she waited patiently.
+
+"Once," said the Mock Turtle at last, with a deep sigh, "I was a real
+Turtle."
+
+These words were followed by a very long silence, broken only by an
+occasional exclamation of "Hjckrrh!" from the Gryphon, and the constant
+heavy sobbing of the Mock Turtle. Alice was very nearly getting up and
+saying "Thank you, sir, for your interesting story," but she could not
+help thinking there _must_ be more to come, so she sat still and said
+nothing.
+
+"When we were little," the Mock Turtle went on at last, more calmly,
+though still sobbing a little now and then, "we went to school in the
+sea. The master was an old Turtle--we used to call him Tortoise----"
+
+"Why did you call him Tortoise, if he wasn't one?" Alice asked.
+
+"We called him Tortoise because he taught us," said the Mock Turtle
+angrily: "really you are very dull!"
+
+"You ought to be ashamed of yourself for asking such a simple question,"
+added the Gryphon; and then they both sat silent and looked at poor
+Alice, who felt ready to sink into the earth. At last the Gryphon said
+to the Mock Turtle, "Drive on, old fellow. Don't be all day about it!"
+and he went on in these words:
+
+"Yes, we went to school in the sea, though you mayn't believe it----"
+
+"I never said I didn't!" interrupted Alice.
+
+"You did," said the Mock Turtle.
+
+"Hold your tongue!" added the Gryphon, before Alice could speak again.
+The Mock Turtle went on:--
+
+"We had the best of educations--in fact, we went to school every
+day----"
+
+"_I've_ been to a day-school, too," said Alice; "you needn't be so proud
+as all that."
+
+"With extras?" asked the Mock Turtle a little anxiously.
+
+"Yes," said Alice, "we learned French and music."
+
+"And washing?" said the Mock Turtle.
+
+"Certainly not!" said Alice indignantly.
+
+"Ah! then yours wasn't a really good school," said the Mock Turtle in a
+tone of relief. "Now at _ours_ they had at the end of the bill, 'French,
+music, _and washing_--extra.'"
+
+"You couldn't have wanted it much," said Alice; "living at the bottom of
+the sea."
+
+"I couldn't afford to learn it," said the Mock Turtle with a sigh. "I
+only took the regular course."
+
+"What was that?" inquired Alice.
+
+"Reeling and Writhing, of course, to begin with," the Mock Turtle
+replied; "and then the different branches of Arithmetic--Ambition,
+Distraction, Uglification, and Derision."
+
+"I never heard of 'Uglification,'" Alice ventured to say. "What is it?"
+
+The Gryphon lifted up both its paws in surprise. "Never heard of
+uglifying!" it exclaimed. "You know what to beautify is, I suppose?"
+
+"Yes," said Alice doubtfully: "it means--to--make--anything--prettier."
+
+"Well, then," the Gryphon went on, "if you don't know what to uglify is,
+you are a simpleton."
+
+Alice did not feel encouraged to ask any more questions about it, so she
+turned to the Mock Turtle and said, "What else had you to learn?"
+
+"Well, there was Mystery," the Mock Turtle replied, counting off the
+subjects on his flappers, "--Mystery, ancient and modern, with
+Seaography: then Drawling--the Drawling-master was an old conger-eel,
+that used to come once a week: _he_ taught us Drawling, Stretching, and
+Fainting in Coils."
+
+"What was _that_ like?" said Alice.
+
+"Well, I can't show it you myself," the Mock Turtle said: "I'm too
+stiff. And the Gryphon never learnt it."
+
+"Hadn't time," said the Gryphon: "I went to the Classical master,
+though. He was an old crab, _he_ was."
+
+"I never went to him," the Mock Turtle said with a sigh: "he taught
+Laughing and Grief, they used to say."
+
+"So he did, so he did," said the Gryphon, sighing in his turn; and both
+creatures hid their faces in their paws.
+
+"And how many hours a day did you do lessons?" said Alice, in a hurry to
+change the subject.
+
+"Ten hours the first day," said the Mock Turtle: "nine the next, and so
+on."
+
+"What a curious plan!" exclaimed Alice.
+
+"That's the reason they're called lessons," the Gryphon remarked:
+"because they lessen from day to day."
+
+This was quite a new idea to Alice, and she thought over it a little
+before she made her next remark. "Then the eleventh day must have been a
+holiday."
+
+"Of course it was," said the Mock Turtle.
+
+"And how did you manage on the twelfth?" Alice went on eagerly.
+
+"That's enough about lessons," the Gryphon interrupted in a very decided
+tone: "tell her something about the games now."
+
+
+
+
+CHAPTER X
+
+
+[Sidenote: _The Lobster Quadrille_]
+
+THE Mock Turtle sighed deeply, and drew the back of one
+flapper across his eyes. He looked at Alice, and tried to speak, but,
+for a minute or two, sobs choked his voice. "Same as if he had a bone in
+his throat," said the Gryphon: and it set to work shaking him and
+punching him in the back. At last the Mock Turtle recovered his voice,
+and, with tears running down his cheeks, went on again:
+
+"You may not have lived much under the sea--" ("I haven't," said Alice)
+"and perhaps you were never even introduced to a lobster--" (Alice began
+to say "I once tasted----" but checked herself hastily, and said "No,
+never") "--so you can have no idea what a delightful thing a Lobster
+Quadrille is!"
+
+"No, indeed," said Alice. "What sort of a dance is it?"
+
+"Why," said the Gryphon, "you first form into a line along the
+sea-shore----"
+
+"Two lines!" cried the Mock Turtle. "Seals, turtles, and so on; then,
+when you've cleared the jelly-fish out of the way----"
+
+"_That_ generally takes some time," interrupted the Gryphon.
+
+"--you advance twice----"
+
+"Each with a lobster as a partner!" cried the Gryphon.
+
+"Of course," the Mock Turtle said: "advance twice, set to partners----"
+
+"--change lobsters, and retire in same order," continued the Gryphon.
+
+"Then, you know," the Mock Turtle went on, "you throw the----"
+
+"The lobsters!" shouted the Gryphon, with a bound into the air.
+
+"--as far out to sea as you can----"
+
+"Swim, after them!" screamed the Gryphon.
+
+"Turn a somersault in the sea!" cried the Mock Turtle, capering wildly
+about.
+
+"Change lobsters again!" yelled the Gryphon.
+
+"Back to land again, and--that's all the first figure," said the Mock
+Turtle, suddenly dropping his voice; and the two creatures, who had been
+jumping about like mad things all this time, sat down again very sadly
+and quietly, and looked at Alice.
+
+"It must be a very pretty dance," said Alice, timidly.
+
+"Would you like to see a little of it?" said the Mock Turtle.
+
+"Very much indeed," said Alice.
+
+"Come, let's try the first figure!" said the Mock Turtle to the Gryphon.
+"We can do it without lobsters, you know. Which shall sing?"
+
+"Oh, _you_ sing," said the Gryphon. "I've forgotten the words."
+
+So they began solemnly dancing round and round Alice, every now and then
+treading on her toes when they passed too close, and waving their
+forepaws to mark the time, while the Mock Turtle sang this, very slowly
+and sadly:--
+
+ "Will you walk a little faster?" said a whiting to a snail,
+ "There's a porpoise close behind us, and he's treading on my tail.
+ See how eagerly the lobsters and the turtles all advance!
+ They are waiting on the shingle--will you come and join the dance?
+ Will you, won't you, will you, won't you, will you join the dance?
+ Will you, won't you, will you, won't you, won't you join the dance?
+
+ "You can really have no notion how delightful it will be,
+ When they take us up and throw us, with the lobsters, out to sea!"
+ But the snail replied: "Too far, too far!" and gave a look askance--
+ Said he thanked the whiting kindly, but he would not join the dance.
+ Would not, could not, would not, could not, would not join the dance.
+ Would not, could not, would not, could not, could not join the dance.
+
+ "What matters it how far we go?" his scaly friend replied;
+ "There is another shore, you know, upon the other side.
+ The further off from England the nearer is to France--
+ Then turn not pale, beloved snail, but come and join the dance.
+ Will you, won't you, will you, won't you, will you join the dance?
+ Will you, won't you, will you, won't you, won't you join the dance?"
+
+"Thank you, it's a very interesting dance to watch," said Alice, feeling
+very glad that it was over at last: "and I do so like that curious song
+about the whiting!"
+
+"Oh, as to the whiting," said the Mock Turtle, "they--you've seen them,
+of course?"
+
+"Yes," said Alice, "I've often seen them at dinn----" she checked
+herself hastily.
+
+"I don't know where Dinn may be," said the Mock Turtle, "but if you've
+seen them so often, of course you know what they're like."
+
+"I believe so," Alice replied thoughtfully. "They have their tails in
+their mouths--and they're all over crumbs."
+
+"You're wrong about the crumbs," said the Mock Turtle: "crumbs would all
+wash off in the sea. But they _have_ their tails in their mouths; and
+the reason is--" here the Mock Turtle yawned and shut his eyes. "Tell
+her about the reason and all that," he said to the Gryphon.
+
+"The reason is," said the Gryphon, "that they _would_ go with the
+lobsters to the dance. So they got thrown out to sea. So they had to
+fall a long way. So they got their tails fast in their mouths. So they
+couldn't get them out again. That's all."
+
+"Thank you," said Alice. "It's very interesting. I never knew so much
+about a whiting before."
+
+"I can tell you more than that, if you like," said the Gryphon. "Do you
+know why it's called a whiting?"
+
+"I never thought about it," said Alice. "Why?"
+
+"_It does the boots and shoes_," the Gryphon replied very solemnly.
+
+Alice was thoroughly puzzled. "Does the boots and shoes!" she repeated
+in a wondering tone.
+
+"Why, what are _your_ shoes done with?" said the Gryphon. "I mean, what
+makes them so shiny?"
+
+Alice looked down at them, and considered a little before she gave her
+answer. "They're done with blacking, I believe."
+
+"Boots and shoes under the sea," the Gryphon went on in a deep voice,
+"are done with whiting. Now you know."
+
+"And what are they made of?" Alice asked in a tone of great curiosity.
+
+"Soles and eels, of course," the Gryphon replied rather impatiently:
+"any shrimp could have told you that."
+
+"If I'd been the whiting," said Alice, whose thoughts were still running
+on the song, "I'd have said to the porpoise, 'Keep back, please: we
+don't want _you_ with us!'"
+
+"They were obliged to have him with them," the Mock Turtle said: "no
+wise fish would go anywhere without a porpoise."
+
+"Wouldn't it really?" said Alice in a tone of great surprise.
+
+"Of course not," said the Mock Turtle: "why, if a fish came to _me_, and
+told me he was going a journey, I should say, 'With what porpoise?'"
+
+"Don't you mean 'purpose'?" said Alice.
+
+"I mean what I say," the Mock Turtle replied in an offended tone. And
+the Gryphon added, "Come, let's hear some of _your_ adventures."
+
+[Illustration: _The Mock Turtle drew a long breath and said, "That's
+very curious"_]
+
+"I could tell you my adventures--beginning from this morning," said
+Alice a little timidly: "but it's no use going back to yesterday,
+because I was a different person then."
+
+"Explain all that," said the Mock Turtle.
+
+"No, no! The adventures first," said the Gryphon in an impatient tone:
+"explanations take such a dreadful time."
+
+So Alice began telling them her adventures from the time when she first
+saw the White Rabbit. She was a little nervous about it just at first,
+the two creatures got so close to her, one on each side, and opened
+their eyes and mouths so _very_ wide, but she gained courage as she went
+on. Her listeners were perfectly quiet till she got to the part about
+her repeating "_You are old, Father William_," to the Caterpillar, and
+the words all coming different, and then the Mock Turtle drew a long
+breath, and said, "That's very curious."
+
+"It's all about as curious as it can be," said the Gryphon.
+
+"It all came different!" the Mock Turtle repeated thoughtfully. "I
+should like to hear her repeat something now. Tell her to begin." He
+looked at the Gryphon as if he thought it had some kind of authority
+over Alice.
+
+"Stand up and repeat '_'Tis the voice of the sluggard_,'" said the
+Gryphon.
+
+"How the creatures order one about, and make one repeat lessons!"
+thought Alice. "I might as well be at school at once." However, she got
+up, and began to repeat it, but her head was so full of the Lobster
+Quadrille, that she hardly knew what she was saying, and the words came
+very queer indeed:--
+
+ "'Tis the voice of the Lobster; I heard him declare,
+ 'You have baked me too brown, I must sugar my hair.'
+ As a duck with its eyelids, so he with his nose
+ Trims his belt and his buttons, and turns out his toes.
+ When the sands are all dry, he is gay as a lark,
+ And will talk in contemptuous tones of the Shark:
+ But, when the tide rises and sharks are around,
+ His voice has a timid and tremulous sound."
+
+"That's different from what _I_ used to say when I was a child," said
+the Gryphon.
+
+"Well, _I_ never heard it before," said the Mock Turtle: "but it sounds
+uncommon nonsense."
+
+Alice said nothing; she had sat down with her face in her hands,
+wondering if anything would _ever_ happen in a natural way again.
+
+"I should like to have it explained," said the Mock Turtle.
+
+"She ca'n't explain it," hastily said the Gryphon. "Go on with the next
+verse."
+
+"But about his toes?" the Mock Turtle persisted. "How _could_ he turn
+them out with his nose, you know?"
+
+"It's the first position in dancing," Alice said; but was dreadfully
+puzzled by the whole thing, and longed to change the subject.
+
+"Go on with the next verse," the Gryphon repeated: "it begins '_I passed
+by his garden_.'"
+
+Alice did not dare to disobey, though she felt sure it would all come
+wrong, and she went on in a trembling voice:
+
+ "I passed by his garden, and marked, with one eye,
+ How the Owl and the Panther were sharing a pie:
+ The Panther took pie-crust, and gravy, and meat,
+ While the Owl had the dish as its share of the treat.
+ When the pie was all finished, the Owl, as a boon,
+ Was kindly permitted to pocket the spoon:
+ While the Panther received knife and fork with a growl,
+ And concluded the banquet by----"
+
+"What _is_ the use of repeating all that stuff," the Mock Turtle
+interrupted, "if you don't explain it as you go on? It's by far the most
+confusing thing _I_ ever heard!"
+
+[Illustration]
+
+"Yes, I think you'd better leave off," said the Gryphon: and Alice was
+only too glad to do so.
+
+"Shall we try another figure of the Lobster Quadrille?" the Gryphon went
+on. "Or would you like the Mock Turtle to sing you another song?"
+
+"Oh, a song, please, if the Mock Turtle would be so kind," Alice
+replied, so eagerly that the Gryphon said, in a rather offended tone,
+"H'm! No accounting for tastes! Sing her '_Turtle Soup_,' will you, old
+fellow?"
+
+The Mock Turtle sighed deeply, and began, in a voice choked with sobs,
+to sing this:--
+
+ "Beautiful Soup, so rich and green,
+ Waiting in a hot tureen!
+ Who for such dainties would not stoop?
+ Soup of the evening, beautiful Soup!
+ Soup of the evening, beautiful Soup!
+ Beau--ootiful Soo--oop!
+ Beau--ootiful Soo--oop!
+ Soo--oop of the e--e--evening,
+ Beautiful, beautiful Soup!
+
+ "Beautiful Soup! Who cares for fish,
+ Game, or any other dish?
+ Who would not give all else for two
+ Pennyworth only of beautiful Soup?
+ Pennyworth only of beautiful Soup?
+ Beau--ootiful Soo--oop!
+ Beau--ootiful Soo--oop!
+ Soo--oop of the e--e--evening,
+ Beautiful, beauti--FUL SOUP!"
+
+"Chorus again!" cried the Gryphon, and the Mock Turtle had just begun
+to repeat it, when a cry of "The trial's beginning!" was heard in the
+distance.
+
+"Come on!" cried the Gryphon, and, taking Alice by the hand, it hurried
+off, without waiting for the end of the song.
+
+"What trial is it?" Alice panted as she ran; but the Gryphon only
+answered "Come on!" and ran the faster, while more and more faintly
+came, carried on the breeze that followed them, the melancholy words:--
+
+ "Soo--oop of the e--e--evening,
+ Beautiful, beautiful Soup!"
+
+
+
+
+CHAPTER XI
+
+
+[Sidenote: _Who Stole the Tarts?_]
+
+THE King and Queen of Hearts were seated on their throne
+when they arrived, with a great crowd assembled about them--all sorts of
+little birds and beasts, as well as the whole pack of cards: the Knave
+was standing before them, in chains, with a soldier on each side to
+guard him; and near the King was the White Rabbit, with a trumpet in one
+hand, and a scroll of parchment in the other. In the very middle of the
+court was a table, with a large dish of tarts upon it: they looked so
+good, that it made Alice quite hungry to look at them--"I wish they'd
+get the trial done," she thought, "and hand round the refreshments!" But
+there seemed to be no chance of this, so she began looking about her, to
+pass away the time.
+
+Alice had never been in a court of justice before, but she had read
+about them in books, and she was quite pleased to find that she knew the
+name of nearly everything there. "That's the judge," she said to
+herself, "because of his great wig."
+
+The judge, by the way, was the King; and as he wore his crown over the
+wig, he did not look at all comfortable, and it was certainly not
+becoming.
+
+"And that's the jury-box," thought Alice, "and those twelve creatures,"
+(she was obliged to say "creatures," you see, because some of them were
+animals, and some were birds,) "I suppose they are the jurors." She said
+this last word two or three times over to herself, being rather proud of
+it: for she thought, and rightly too, that very few little girls of her
+age knew the meaning of it at all. However, "jurymen" would have done
+just as well.
+
+The twelve jurors were all writing very busily on slates. "What are they
+all doing?" Alice whispered to the Gryphon. "They can't have anything to
+put down yet, before the trial's begun."
+
+[Illustration: _Who stole the tarts?_]
+
+"They're putting down their names," the Gryphon whispered in reply,
+"for fear they should forget them before the end of the trial."
+
+"Stupid things!" Alice began in a loud, indignant voice, but she stopped
+hastily, for the White Rabbit cried out "Silence in the court!" and the
+King put on his spectacles and looked anxiously round, to see who was
+talking.
+
+Alice could see, as well as if she were looking over their shoulders,
+that all the jurors were writing down "stupid things!" on their slates,
+and she could even make out that one of them didn't know how to spell
+"stupid," and that he had to ask his neighbour to tell him. "A nice
+muddle their slates will be in before the trial's over!" thought Alice.
+
+One of the jurors had a pencil that squeaked. This, of course, Alice
+could _not_ stand, and she went round the court and got behind him, and
+very soon found an opportunity of taking it away. She did it so quickly
+that the poor little juror (it was Bill, the Lizard) could not make out
+at all what had become of it; so, after hunting all about for it, he
+was obliged to write with one finger for the rest of the day; and this
+was of very little use, as it left no mark on the slate.
+
+"Herald, read the accusation!" said the King.
+
+On this the White Rabbit blew three blasts on the trumpet, and then
+unrolled the parchment scroll, and read as follows:
+
+ "The Queen of Hearts, she made some tarts,
+ All on a summer day:
+ The Knave of Hearts, he stole those tarts,
+ And took them quite away!"
+
+"Consider your verdict," the King said to the jury.
+
+"Not yet, not yet!" the Rabbit hastily interrupted. "There's a great
+deal to come before that!"
+
+"Call the first witness," said the King; and the Rabbit blew three
+blasts on the trumpet, and called out "First witness!"
+
+The first witness was the Hatter. He came in with a teacup in one hand
+and a piece of bread-and-butter in the other. "I beg pardon, your
+Majesty," he began, "for bringing these in; but I hadn't quite finished
+my tea when I was sent for."
+
+"You ought to have finished," said the King. "When did you begin?"
+
+The Hatter looked at the March Hare, who had followed him into the
+court, arm-in-arm with the Dormouse. "Fourteenth of March, I _think_ it
+was," he said.
+
+"Fifteenth," said the March Hare.
+
+"Sixteenth," said the Dormouse.
+
+"Write that down," the King said to the jury, and the jury eagerly wrote
+down all three dates on their slates, and then added them up, and
+reduced the answer to shillings and pence.
+
+"Take off your hat," the King said to the Hatter.
+
+"It isn't mine," said the Hatter.
+
+"_Stolen!_" the King exclaimed, turning to the jury, who instantly made
+a memorandum of the fact.
+
+"I keep them to sell," the Hatter added as an explanation: "I've none of
+my own. I'm a hatter."
+
+Here the Queen put on her spectacles, and began staring hard at the
+Hatter, who turned pale and fidgeted.
+
+"Give your evidence," said the King; "and don't be nervous, or I'll have
+you executed on the spot."
+
+This did not seem to encourage the witness at all: he kept shifting from
+one foot to the other, looking uneasily at the Queen, and in his
+confusion he bit a large piece out of his teacup instead of the
+bread-and-butter.
+
+Just at this moment Alice felt a very curious sensation, which puzzled
+her a good deal until she made out what it was: she was beginning to
+grow larger again, and she thought at first she would get up and leave
+the court; but on second thoughts she decided to remain where she was as
+long as there was room for her.
+
+"I wish you wouldn't squeeze so," said the Dormouse, who was sitting
+next to her. "I can hardly breathe."
+
+"I can't help it," said Alice very meekly: "I'm growing."
+
+"You've no right to grow _here_," said the Dormouse.
+
+"Don't talk nonsense," said Alice more boldly: "you know you're growing
+too."
+
+"Yes, but _I_ grow at a reasonable pace," said the Dormouse; "not in
+that ridiculous fashion." And he got up very sulkily and crossed over to
+the other side of the court.
+
+All this time the Queen had never left off staring at the Hatter, and,
+just as the Dormouse crossed the court, she said to one of the officers
+of the court, "Bring me the list of the singers in the last concert!" on
+which the wretched Hatter trembled so, that he shook off both his shoes.
+
+"Give your evidence," the King repeated angrily, "or I'll have you
+executed, whether you're nervous or not."
+
+"I'm a poor man, your Majesty," the Hatter began, in a trembling voice,
+"--and I hadn't begun my tea--not above a week or so--and what with the
+bread-and-butter getting so thin--and the twinkling of the tea----"
+
+"The twinkling of _what_?" said the King.
+
+"It _began_ with the tea," the Hatter replied.
+
+"Of course twinkling _begins_ with a T!" said the King sharply. "Do you
+take me for a dunce? Go on!"
+
+"I'm a poor man," the Hatter went on, "and most things twinkled after
+that--only the March Hare said----"
+
+"I didn't!" the March Hare interrupted in a great hurry.
+
+"You did!" said the Hatter.
+
+"I deny it!" said the March Hare.
+
+"He denies it," said the King: "leave out that part."
+
+"Well, at any rate, the Dormouse said----" the Hatter went on, looking
+anxiously round to see if he would deny it too: but the Dormouse denied
+nothing, being fast asleep.
+
+"After that," continued the Hatter, "I cut some more
+bread-and-butter----"
+
+"But what did the Dormouse say?" one of the jury asked.
+
+"That I can't remember," said the Hatter.
+
+"You _must_ remember," remarked the King, "or I'll have you executed."
+
+The miserable Hatter dropped his teacup and bread-and-butter, and went
+down on one knee. "I'm a poor man, your Majesty," he began.
+
+"You're a _very_ poor _speaker_," said the King.
+
+Here one of the guinea-pigs cheered, and was immediately suppressed by
+the officers of the court. (As that is rather a hard word, I will just
+explain to you how it was done. They had a large canvas bag, which tied
+up at the mouth with strings: into this they slipped the guinea-pig,
+head first, and then sat upon it.)
+
+"I'm glad I've seen that done," thought Alice. "I've so often read in
+the newspapers, at the end of trials, 'There was some attempt at
+applause, which was immediately suppressed by the officers of the
+court,' and I never understood what it meant till now."
+
+"If that's all you know about it, you may stand down," continued the
+King.
+
+"I can't go no lower," said the Hatter: "I'm on the floor, as it is."
+
+"Then you may _sit_ down," the King replied.
+
+Here the other guinea-pig cheered, and was suppressed.
+
+"Come, that finishes the guinea-pigs!" thought Alice. "Now we shall get
+on better."
+
+"I'd rather finish my tea," said the Hatter, with an anxious look at
+the Queen, who was reading the list of singers.
+
+"You may go," said the King; and the Hatter hurriedly left the court,
+without even waiting to put his shoes on.
+
+"--and just take his head off outside," the Queen added to one of the
+officers; but the Hatter was out of sight before the officer could get
+to the door.
+
+"Call the next witness!" said the King.
+
+The next witness was the Duchess's cook. She carried the pepper-box in
+her hand, and Alice guessed who it was, even before she got into the
+court, by the way the people near the door began sneezing all at once.
+
+"Give your evidence," said the King.
+
+"Sha'n't," said the cook.
+
+The King looked anxiously at the White Rabbit, who said in a low voice,
+"Your Majesty must cross-examine _this_ witness."
+
+"Well, if I must, I must," the King said with a melancholy air, and,
+after folding his arms and frowning at the cook till his eyes were
+nearly out of sight, he said in a deep voice, "What are tarts made of?"
+
+"Pepper, mostly," said the cook.
+
+"Treacle," said a sleepy voice behind her.
+
+"Collar that Dormouse," the Queen shrieked out. "Behead that Dormouse!
+Turn that Dormouse out of court! Suppress him! Pinch him! Off with his
+whiskers."
+
+For some minutes the whole court was in confusion, getting the Dormouse
+turned out, and, by the time they had settled down again, the cook had
+disappeared.
+
+[Illustration]
+
+"Never mind!" said the King, with an air of great relief. "Call the next
+witness." And he added in an undertone to the Queen, "Really, my dear,
+_you_ must cross-examine the next witness. It quite makes my forehead
+ache!"
+
+Alice watched the White Rabbit as he fumbled over the list, feeling very
+curious to see what the next witness would be like, "--for they haven't
+got much evidence _yet_," she said to herself. Imagine her surprise,
+when the White Rabbit read out, at the top of his shrill little voice,
+the name "Alice!"
+
+
+
+
+CHAPTER XII
+
+
+[Sidenote: _Alice's Evidence_]
+
+"HERE!" cried Alice, quite forgetting in the flurry of
+the moment how large she had grown in the last few minutes, and she
+jumped up in such a hurry that she tipped over the jury-box with the
+edge of her skirt, upsetting all the jurymen on to the heads of the
+crowd below, and there they lay sprawling about, reminding her very much
+of a globe of gold-fish she had accidentally upset the week before.
+
+"Oh, I _beg_ your pardon!" she exclaimed in a tone of great dismay, and
+began picking them up again as quickly as she could, for the accident of
+the gold-fish kept running in her head, and she had a vague sort of idea
+that they must be collected at once and put back into the jury-box, or
+they would die.
+
+"The trial cannot proceed," said the King in a very grave voice, "until
+all the jurymen are back in their proper places--_all_," he repeated
+with great emphasis, looking hard at Alice as he said so.
+
+Alice looked at the jury-box, and saw that, in her haste, she had put
+the Lizard in head downwards, and the poor little thing was waving its
+tail about in a melancholy way, being quite unable to move. She soon got
+it out again, and put it right; "not that it signifies much," she said
+to herself; "I should think it would be _quite_ as much use in the trial
+one way up as the other."
+
+As soon as the jury had a little recovered from the shock of being
+upset, and their slates and pencils had been found and handed back to
+them, they set to work very diligently to write out a history of the
+accident, all except the Lizard, who seemed too much overcome to do
+anything but sit with its mouth open, gazing up into the roof of the
+court.
+
+"What do you know about this business?" the King said to Alice.
+
+"Nothing," said Alice.
+
+"Nothing _whatever_?" persisted the King.
+
+"Nothing whatever," said Alice.
+
+"That's very important," the King said, turning to the jury. They were
+just beginning to write this down on their slates, when the White Rabbit
+interrupted: "_Un_important, your Majesty means, of course," he said in
+a very respectful tone, but frowning and making faces at him as he
+spoke.
+
+"_Un_important, of course, I meant," the King hastily said, and went on
+himself in an undertone,"important--unimportant--unimportant--important----"
+as if he were trying which word sounded best.
+
+Some of the jury wrote it down "important," and some "unimportant."
+Alice could see this, as she was near enough to look over their slates;
+"but it doesn't matter a bit," she thought to herself.
+
+At this moment the King, who had been for some time busily writing in
+his note-book, called out "Silence!" and read out from his book, "Rule
+Forty-two. _All persons more than a mile high to leave the court._"
+
+Everybody looked at Alice.
+
+"_I'm_ not a mile high," said Alice.
+
+"You are," said the King.
+
+"Nearly two miles high," added the Queen.
+
+"Well, I sha'n't go, at any rate," said Alice: "besides, that's not a
+regular rule: you invented it just now."
+
+"It's the oldest rule in the book," said the King.
+
+"Then it ought to be Number One," said Alice.
+
+The King turned pale, and shut his note-book hastily. "Consider your
+verdict," he said to the jury, in a low trembling voice.
+
+"There's more evidence to come yet, please your Majesty," said the White
+Rabbit, jumping up in a great hurry: "this paper has just been picked
+up."
+
+"What's in it?" said the Queen.
+
+"I haven't opened it yet," said the White Rabbit, "but it seems to be a
+letter, written by the prisoner to--to somebody."
+
+"It must have been that," said the King, "unless it was written to
+nobody, which isn't usual, you know."
+
+"Who is it directed to?" said one of the jurymen.
+
+"It isn't directed at all," said the White Rabbit; "in fact, there's
+nothing written on the _outside_." He unfolded the paper as he spoke,
+and added "It isn't a letter after all: it's a set of verses."
+
+"Are they in the prisoner's handwriting?" asked another of the jurymen.
+
+"No, they're not," said the White Rabbit, "and that's the queerest thing
+about it." (The jury all looked puzzled.)
+
+"He must have imitated somebody else's hand," said the King. (The jury
+all brightened up again.)
+
+"Please your Majesty," said the Knave, "I didn't write it, and they
+can't prove that I did: there's no name signed at the end."
+
+"If you didn't sign it," said the King, "that only makes the matter
+worse. You _must_ have meant some mischief, or else you'd have signed
+your name like an honest man."
+
+There was a general clapping of hands at this: it was the first really
+clever thing the King had said that day.
+
+"That _proves_ his guilt, of course," said the Queen: "so, off with----"
+
+"It doesn't prove anything of the sort!" said Alice. "Why, you don't
+even know what they're about!"
+
+"Read them," said the King.
+
+The White Rabbit put on his spectacles. "Where shall I begin, please
+your Majesty?" he asked.
+
+"Begin at the beginning," the King said gravely, "and go on till you
+come to the end; then stop."
+
+There was dead silence in the court, whilst the White Rabbit read out
+these verses:--
+
+ "They told me you had been to her,
+ And mentioned me to him:
+ She gave me a good character,
+ But said I could not swim.
+
+ He sent them word I had not gone,
+ (We know it to be true):
+ If she should push the matter on,
+ What would become of you?
+
+ I gave her one, they gave him two,
+ You gave us three or more;
+ They all returned from him to you,
+ Though they were mine before.
+
+ If I or she should chance to be
+ Involved in this affair,
+ He trusts to you to set them free,
+ Exactly as we were.
+
+ My notion was that you had been
+ (Before she had this fit)
+ An obstacle that came between
+ Him, and ourselves, and it.
+
+ Don't let him know she liked them best,
+ For this must ever be
+ A secret, kept from all the rest,
+ Between yourself and me."
+
+"That's the most important piece of evidence we've heard yet," said the
+King, rubbing his hands; "so now let the jury----"
+
+"If any of them can explain it," said Alice, (she had grown so large in
+the last few minutes that she wasn't a bit afraid of interrupting him,)
+"I'll give him sixpence. _I_ don't believe there's an atom of meaning in
+it."
+
+The jury all wrote down on their slates, "_She_ doesn't believe there's
+an atom of meaning in it," but none of them attempted to explain the
+paper.
+
+"If there's no meaning in it," said the King, "that saves a world of
+trouble, you know, as we needn't try to find any. And yet I don't
+know," he went on, spreading out the verses on his knee, and looking at
+them with one eye; "I seem to see some meaning in them after all.
+'----_said I could not swim_--' you can't swim can you?" he added,
+turning to the Knave.
+
+The Knave shook his head sadly. "Do I look like it?" he said. (Which he
+certainly did _not_, being made entirely of cardboard.)
+
+"All right, so far," said the King, as he went on muttering over the
+verses to himself: "'_We know it to be true_--' that's the jury, of
+course--'_If she should push the matter on_'--that must be the
+Queen--'_What would become of you?_'--What, indeed!--'_I gave her one,
+they gave him two_--' why, that must be what he did with the tarts, you
+know----"
+
+"But it goes on '_they all returned from him to you_,'" said Alice.
+
+"Why, there they are!" said the King triumphantly, pointing to the tarts
+on the table. "Nothing can be clearer than _that_. Then again--'_before
+she had this fit_--' you never had _fits_, my dear, I think?" he said to
+the Queen.
+
+"Never!" said the Queen furiously, throwing an inkstand at the Lizard
+as she spoke. (The unfortunate little Bill had left off writing on his
+slate with one finger, as he found it made no mark; but he now hastily
+began again, using the ink, that was trickling down his face, as long as
+it lasted.)
+
+"Then the words don't _fit_ you," said the King, looking round the court
+with a smile. There was a dead silence.
+
+"It's a pun!" the King added in an angry tone, and everybody laughed.
+
+"Let the jury consider their verdict," the King said, for about the
+twentieth time that day.
+
+"No, no!" said the Queen. "Sentence first--verdict afterwards."
+
+"Stuff and nonsense!" said Alice loudly. "The idea of having the
+sentence first!"
+
+"Hold your tongue!" said the Queen, turning purple.
+
+"I won't!" said Alice.
+
+"Off with her head!" the Queen shouted at the top of her voice. Nobody
+moved.
+
+"Who cares for _you_?" said Alice (she had grown to her full size by
+this time). "You're nothing but a pack of cards!"
+
+[Illustration: _At this the whole pack rose up into the air, and came
+flying down upon her_]
+
+At this the whole pack rose up into the air, and came flying down upon
+her: she gave a little scream, half of fright and half of anger, and
+tried to beat them off, and found herself lying on the bank, with her
+head in the lap of her sister, who was gently brushing away some dead
+leaves that had fluttered down from the trees upon her face.
+
+"Wake up, Alice dear!" said her sister. "Why, what a long sleep you've
+had!"
+
+"Oh, I've had such a curious dream!" said Alice, and she told her
+sister, as well as she could remember them, all these strange Adventures
+of hers that you have just been reading about; and when she had
+finished, her sister kissed her, and said "It _was_ a curious dream,
+dear, certainly: but now run in to your tea; it's getting late." So
+Alice got up and ran off, thinking while she ran, as well she might,
+what a wonderful dream it had been.
+
+
+
+
+BUT her sister sat still just as she had left her, leaning her head,
+watching the setting sun, and thinking of little Alice and all her
+wonderful Adventures, till she too began dreaming after a fashion, and
+this was her dream:
+
+First, she dreamed of little Alice herself, and once again the tiny
+hands were clasped upon her knee, and the bright eager eyes were looking
+up into hers--she could hear the very tones of her voice, and see that
+queer little toss of her head to keep back the wandering hair that
+_would_ always get into her eyes--and still as she listened, or seemed
+to listen, the whole place around her became alive with the strange
+creatures of her little sister's dream.
+
+The long grass rustled at her feet as the White Rabbit hurried by--the
+frightened Mouse splashed his way through the neighbouring pool--she
+could hear the rattle of the teacups as the March Hare and his friends
+shared their never-ending meal, and the shrill voice of the Queen
+ordering off her unfortunate guests to execution--once more the pig-baby
+was sneezing on the Duchess' knee, while plates and dishes crashed
+around it--once more the shriek of the Gryphon, the squeaking of the
+Lizard's slate-pencil, and the choking of the suppressed guinea-pigs,
+filled the air, mixed up with the distant sobs of the miserable Mock
+Turtle.
+
+So she sat on with closed eyes, and half believed herself in Wonderland,
+though she knew she had but to open them again, and all would change to
+dull reality--the grass would be only rustling in the wind, and the pool
+rippling to the waving of the reeds--the rattling teacups would change
+to the tinkling sheep-bells, and the Queen's shrill cries to the voice
+of the shepherd boy--and the sneeze of the baby, the shriek of the
+Gryphon, and all the other queer noises, would change (she knew) to the
+confused clamour of the busy farm-yard--while the lowing of the cattle
+in the distance would take the place of the Mock Turtle's heavy sobs.
+
+Lastly, she pictured to herself how this same little sister of hers
+would, in the after-time, be herself a grown woman; and how she would
+keep, through all her riper years, the simple and loving heart of her
+childhood: and how she would gather about her other little children,
+and make _their_ eyes bright and eager with many a strange tale, perhaps
+even with the dream of Wonderland of long ago: and how she would feel
+with all their simple sorrows, and find a pleasure in all their simple
+joys, remembering her own child-life, and the happy summer days.
+
+
+THE END
+
+
+
+
+ ILLUSTRATIONS REPRODUCED BY HENTSCHEL COLOURTYPE
+ TEXT PRINTED BY BALLANTYNE & COMPANY LTD
+ AT THE BALLANTYNE PRESS
+ TAVISTOCK STREET
+ LONDON
+
+ * * * * *
+
+Transcriber's Notes:
+
+Page 8, opening quote added to text (doorway; "and even if)
+
+Page 33, "she" changed to "she's" (And she's such a)
+
+Page 37, "quiet" changed to "quite" (I'm quite tired of)
+
+Page 41, colon changed to period (arm, yer honour.)
+
+Page 42, "wont" changed to "want" (want to stay)
+
+Page 66, closing quotation mark added (to-morrow----")
+
+Page 69, single quotation mark changed to double (cat," said the
+Duchess)
+
+Page 91, word "to" added to text (minute or two to)
+
+Page 103, word "as" added to the text (just as she had)
+
+Page 104, "hedge-hog" changed to "hedgehog" (send the hedgehog to)
+
+Page 126, end parenthesis added ("No, never")
+
+Page 153, added an apostrophe (What's in it?)
+
+
+
+
+
+
+End of Project Gutenberg's Alice's Adventures in Wonderland, by Lewis Carroll
+
+*** END OF THIS PROJECT GUTENBERG EBOOK ALICE'S ADVENTURES IN WONDERLAND ***
+
+***** This file should be named 28885-8.txt or 28885-8.zip *****
+This and all associated files of various formats will be found in:
+ http://www.gutenberg.org/2/8/8/8/28885/
+
+Produced by Jana Srna, Emmy and the Online Distributed
+Proofreading Team at http://www.pgdp.net (This file was
+produced from images generously made available by the
+University of Florida Digital Collections.)
+
+
+Updated editions will replace the previous one--the old editions
+will be renamed.
+
+Creating the works from public domain print editions means that no
+one owns a United States copyright in these works, so the Foundation
+(and you!) can copy and distribute it in the United States without
+permission and without paying copyright royalties. Special rules,
+set forth in the General Terms of Use part of this license, apply to
+copying and distributing Project Gutenberg-tm electronic works to
+protect the PROJECT GUTENBERG-tm concept and trademark. Project
+Gutenberg is a registered trademark, and may not be used if you
+charge for the eBooks, unless you receive specific permission. If you
+do not charge anything for copies of this eBook, complying with the
+rules is very easy. You may use this eBook for nearly any purpose
+such as creation of derivative works, reports, performances and
+research. They may be modified and printed and given away--you may do
+practically ANYTHING with public domain eBooks. Redistribution is
+subject to the trademark license, especially commercial
+redistribution.
+
+
+
+*** START: FULL LICENSE ***
+
+THE FULL PROJECT GUTENBERG LICENSE
+PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK
+
+To protect the Project Gutenberg-tm mission of promoting the free
+distribution of electronic works, by using or distributing this work
+(or any other work associated in any way with the phrase "Project
+Gutenberg"), you agree to comply with all the terms of the Full Project
+Gutenberg-tm License (available with this file or online at
+http://gutenberg.net/license).
+
+
+Section 1. General Terms of Use and Redistributing Project Gutenberg-tm
+electronic works
+
+1.A. By reading or using any part of this Project Gutenberg-tm
+electronic work, you indicate that you have read, understand, agree to
+and accept all the terms of this license and intellectual property
+(trademark/copyright) agreement. If you do not agree to abide by all
+the terms of this agreement, you must cease using and return or destroy
+all copies of Project Gutenberg-tm electronic works in your possession.
+If you paid a fee for obtaining a copy of or access to a Project
+Gutenberg-tm electronic work and you do not agree to be bound by the
+terms of this agreement, you may obtain a refund from the person or
+entity to whom you paid the fee as set forth in paragraph 1.E.8.
+
+1.B. "Project Gutenberg" is a registered trademark. It may only be
+used on or associated in any way with an electronic work by people who
+agree to be bound by the terms of this agreement. There are a few
+things that you can do with most Project Gutenberg-tm electronic works
+even without complying with the full terms of this agreement. See
+paragraph 1.C below. There are a lot of things you can do with Project
+Gutenberg-tm electronic works if you follow the terms of this agreement
+and help preserve free future access to Project Gutenberg-tm electronic
+works. See paragraph 1.E below.
+
+1.C. The Project Gutenberg Literary Archive Foundation ("the Foundation"
+or PGLAF), owns a compilation copyright in the collection of Project
+Gutenberg-tm electronic works. Nearly all the individual works in the
+collection are in the public domain in the United States. If an
+individual work is in the public domain in the United States and you are
+located in the United States, we do not claim a right to prevent you from
+copying, distributing, performing, displaying or creating derivative
+works based on the work as long as all references to Project Gutenberg
+are removed. Of course, we hope that you will support the Project
+Gutenberg-tm mission of promoting free access to electronic works by
+freely sharing Project Gutenberg-tm works in compliance with the terms of
+this agreement for keeping the Project Gutenberg-tm name associated with
+the work. You can easily comply with the terms of this agreement by
+keeping this work in the same format with its attached full Project
+Gutenberg-tm License when you share it without charge with others.
+
+1.D. The copyright laws of the place where you are located also govern
+what you can do with this work. Copyright laws in most countries are in
+a constant state of change. If you are outside the United States, check
+the laws of your country in addition to the terms of this agreement
+before downloading, copying, displaying, performing, distributing or
+creating derivative works based on this work or any other Project
+Gutenberg-tm work. The Foundation makes no representations concerning
+the copyright status of any work in any country outside the United
+States.
+
+1.E. Unless you have removed all references to Project Gutenberg:
+
+1.E.1. The following sentence, with active links to, or other immediate
+access to, the full Project Gutenberg-tm License must appear prominently
+whenever any copy of a Project Gutenberg-tm work (any work on which the
+phrase "Project Gutenberg" appears, or with which the phrase "Project
+Gutenberg" is associated) is accessed, displayed, performed, viewed,
+copied or distributed:
+
+This eBook is for the use of anyone anywhere at no cost and with
+almost no restrictions whatsoever. You may copy it, give it away or
+re-use it under the terms of the Project Gutenberg License included
+with this eBook or online at www.gutenberg.net
+
+1.E.2. If an individual Project Gutenberg-tm electronic work is derived
+from the public domain (does not contain a notice indicating that it is
+posted with permission of the copyright holder), the work can be copied
+and distributed to anyone in the United States without paying any fees
+or charges. If you are redistributing or providing access to a work
+with the phrase "Project Gutenberg" associated with or appearing on the
+work, you must comply either with the requirements of paragraphs 1.E.1
+through 1.E.7 or obtain permission for the use of the work and the
+Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or
+1.E.9.
+
+1.E.3. If an individual Project Gutenberg-tm electronic work is posted
+with the permission of the copyright holder, your use and distribution
+must comply with both paragraphs 1.E.1 through 1.E.7 and any additional
+terms imposed by the copyright holder. Additional terms will be linked
+to the Project Gutenberg-tm License for all works posted with the
+permission of the copyright holder found at the beginning of this work.
+
+1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm
+License terms from this work, or any files containing a part of this
+work or any other work associated with Project Gutenberg-tm.
+
+1.E.5. Do not copy, display, perform, distribute or redistribute this
+electronic work, or any part of this electronic work, without
+prominently displaying the sentence set forth in paragraph 1.E.1 with
+active links or immediate access to the full terms of the Project
+Gutenberg-tm License.
+
+1.E.6. You may convert to and distribute this work in any binary,
+compressed, marked up, nonproprietary or proprietary form, including any
+word processing or hypertext form. However, if you provide access to or
+distribute copies of a Project Gutenberg-tm work in a format other than
+"Plain Vanilla ASCII" or other format used in the official version
+posted on the official Project Gutenberg-tm web site (www.gutenberg.net),
+you must, at no additional cost, fee or expense to the user, provide a
+copy, a means of exporting a copy, or a means of obtaining a copy upon
+request, of the work in its original "Plain Vanilla ASCII" or other
+form. Any alternate format must include the full Project Gutenberg-tm
+License as specified in paragraph 1.E.1.
+
+1.E.7. Do not charge a fee for access to, viewing, displaying,
+performing, copying or distributing any Project Gutenberg-tm works
+unless you comply with paragraph 1.E.8 or 1.E.9.
+
+1.E.8. You may charge a reasonable fee for copies of or providing
+access to or distributing Project Gutenberg-tm electronic works provided
+that
+
+- You pay a royalty fee of 20% of the gross profits you derive from
+ the use of Project Gutenberg-tm works calculated using the method
+ you already use to calculate your applicable taxes. The fee is
+ owed to the owner of the Project Gutenberg-tm trademark, but he
+ has agreed to donate royalties under this paragraph to the
+ Project Gutenberg Literary Archive Foundation. Royalty payments
+ must be paid within 60 days following each date on which you
+ prepare (or are legally required to prepare) your periodic tax
+ returns. Royalty payments should be clearly marked as such and
+ sent to the Project Gutenberg Literary Archive Foundation at the
+ address specified in Section 4, "Information about donations to
+ the Project Gutenberg Literary Archive Foundation."
+
+- You provide a full refund of any money paid by a user who notifies
+ you in writing (or by e-mail) within 30 days of receipt that s/he
+ does not agree to the terms of the full Project Gutenberg-tm
+ License. You must require such a user to return or
+ destroy all copies of the works possessed in a physical medium
+ and discontinue all use of and all access to other copies of
+ Project Gutenberg-tm works.
+
+- You provide, in accordance with paragraph 1.F.3, a full refund of any
+ money paid for a work or a replacement copy, if a defect in the
+ electronic work is discovered and reported to you within 90 days
+ of receipt of the work.
+
+- You comply with all other terms of this agreement for free
+ distribution of Project Gutenberg-tm works.
+
+1.E.9. If you wish to charge a fee or distribute a Project Gutenberg-tm
+electronic work or group of works on different terms than are set
+forth in this agreement, you must obtain permission in writing from
+both the Project Gutenberg Literary Archive Foundation and Michael
+Hart, the owner of the Project Gutenberg-tm trademark. Contact the
+Foundation as set forth in Section 3 below.
+
+1.F.
+
+1.F.1. Project Gutenberg volunteers and employees expend considerable
+effort to identify, do copyright research on, transcribe and proofread
+public domain works in creating the Project Gutenberg-tm
+collection. Despite these efforts, Project Gutenberg-tm electronic
+works, and the medium on which they may be stored, may contain
+"Defects," such as, but not limited to, incomplete, inaccurate or
+corrupt data, transcription errors, a copyright or other intellectual
+property infringement, a defective or damaged disk or other medium, a
+computer virus, or computer codes that damage or cannot be read by
+your equipment.
+
+1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right
+of Replacement or Refund" described in paragraph 1.F.3, the Project
+Gutenberg Literary Archive Foundation, the owner of the Project
+Gutenberg-tm trademark, and any other party distributing a Project
+Gutenberg-tm electronic work under this agreement, disclaim all
+liability to you for damages, costs and expenses, including legal
+fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
+LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE
+PROVIDED IN PARAGRAPH F3. YOU AGREE THAT THE FOUNDATION, THE
+TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE
+LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR
+INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a
+defect in this electronic work within 90 days of receiving it, you can
+receive a refund of the money (if any) you paid for it by sending a
+written explanation to the person you received the work from. If you
+received the work on a physical medium, you must return the medium with
+your written explanation. The person or entity that provided you with
+the defective work may elect to provide a replacement copy in lieu of a
+refund. If you received the work electronically, the person or entity
+providing it to you may choose to give you a second opportunity to
+receive the work electronically in lieu of a refund. If the second copy
+is also defective, you may demand a refund in writing without further
+opportunities to fix the problem.
+
+1.F.4. Except for the limited right of replacement or refund set forth
+in paragraph 1.F.3, this work is provided to you 'AS-IS' WITH NO OTHER
+WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE.
+
+1.F.5. Some states do not allow disclaimers of certain implied
+warranties or the exclusion or limitation of certain types of damages.
+If any disclaimer or limitation set forth in this agreement violates the
+law of the state applicable to this agreement, the agreement shall be
+interpreted to make the maximum disclaimer or limitation permitted by
+the applicable state law. The invalidity or unenforceability of any
+provision of this agreement shall not void the remaining provisions.
+
+1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the
+trademark owner, any agent or employee of the Foundation, anyone
+providing copies of Project Gutenberg-tm electronic works in accordance
+with this agreement, and any volunteers associated with the production,
+promotion and distribution of Project Gutenberg-tm electronic works,
+harmless from all liability, costs and expenses, including legal fees,
+that arise directly or indirectly from any of the following which you do
+or cause to occur: (a) distribution of this or any Project Gutenberg-tm
+work, (b) alteration, modification, or additions or deletions to any
+Project Gutenberg-tm work, and (c) any Defect you cause.
+
+
+Section 2. Information about the Mission of Project Gutenberg-tm
+
+Project Gutenberg-tm is synonymous with the free distribution of
+electronic works in formats readable by the widest variety of computers
+including obsolete, old, middle-aged and new computers. It exists
+because of the efforts of hundreds of volunteers and donations from
+people in all walks of life.
+
+Volunteers and financial support to provide volunteers with the
+assistance they need are critical to reaching Project Gutenberg-tm's
+goals and ensuring that the Project Gutenberg-tm collection will
+remain freely available for generations to come. In 2001, the Project
+Gutenberg Literary Archive Foundation was created to provide a secure
+and permanent future for Project Gutenberg-tm and future generations.
+To learn more about the Project Gutenberg Literary Archive Foundation
+and how your efforts and donations can help, see Sections 3 and 4
+and the Foundation web page at http://www.pglaf.org.
+
+
+Section 3. Information about the Project Gutenberg Literary Archive
+Foundation
+
+The Project Gutenberg Literary Archive Foundation is a non profit
+501(c)(3) educational corporation organized under the laws of the
+state of Mississippi and granted tax exempt status by the Internal
+Revenue Service. The Foundation's EIN or federal tax identification
+number is 64-6221541. Its 501(c)(3) letter is posted at
+http://pglaf.org/fundraising. Contributions to the Project Gutenberg
+Literary Archive Foundation are tax deductible to the full extent
+permitted by U.S. federal laws and your state's laws.
+
+The Foundation's principal office is located at 4557 Melan Dr. S.
+Fairbanks, AK, 99712., but its volunteers and employees are scattered
+throughout numerous locations. Its business office is located at
+809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887, email
+business@pglaf.org. Email contact links and up to date contact
+information can be found at the Foundation's web site and official
+page at http://pglaf.org
+
+For additional contact information:
+ Dr. Gregory B. Newby
+ Chief Executive and Director
+ gbnewby@pglaf.org
+
+
+Section 4. Information about Donations to the Project Gutenberg
+Literary Archive Foundation
+
+Project Gutenberg-tm depends upon and cannot survive without wide
+spread public support and donations to carry out its mission of
+increasing the number of public domain and licensed works that can be
+freely distributed in machine readable form accessible by the widest
+array of equipment including outdated equipment. Many small donations
+($1 to $5,000) are particularly important to maintaining tax exempt
+status with the IRS.
+
+The Foundation is committed to complying with the laws regulating
+charities and charitable donations in all 50 states of the United
+States. Compliance requirements are not uniform and it takes a
+considerable effort, much paperwork and many fees to meet and keep up
+with these requirements. We do not solicit donations in locations
+where we have not received written confirmation of compliance. To
+SEND DONATIONS or determine the status of compliance for any
+particular state visit http://pglaf.org
+
+While we cannot and do not solicit contributions from states where we
+have not met the solicitation requirements, we know of no prohibition
+against accepting unsolicited donations from donors in such states who
+approach us with offers to donate.
+
+International donations are gratefully accepted, but we cannot make
+any statements concerning tax treatment of donations received from
+outside the United States. U.S. laws alone swamp our small staff.
+
+Please check the Project Gutenberg Web pages for current donation
+methods and addresses. Donations are accepted in a number of other
+ways including including checks, online payments and credit card
+donations. To donate, please visit: http://pglaf.org/donate
+
+
+Section 5. General Information About Project Gutenberg-tm electronic
+works.
+
+Professor Michael S. Hart is the originator of the Project Gutenberg-tm
+concept of a library of electronic works that could be freely shared
+with anyone. For thirty years, he produced and distributed Project
+Gutenberg-tm eBooks with only a loose network of volunteer support.
+
+
+Project Gutenberg-tm eBooks are often created from several printed
+editions, all of which are confirmed as Public Domain in the U.S.
+unless a copyright notice is included. Thus, we do not necessarily
+keep eBooks in compliance with any particular paper edition.
+
+
+Most people start at our Web site which has the main PG search facility:
+
+ http://www.gutenberg.net
+
+This Web site includes information about Project Gutenberg-tm,
+including how to make donations to the Project Gutenberg Literary
+Archive Foundation, how to help produce our new eBooks, and how to
+subscribe to our email newsletter to hear about new eBooks.
diff --git a/lecture_notes/ult/exercises.rst b/lecture_notes/ult/exercises.rst new file mode 100644 index 0000000..9898b39 --- /dev/null +++ b/lecture_notes/ult/exercises.rst @@ -0,0 +1,109 @@ +Exercises +========= + +Session-1 +--------- + +1. Login to your machine from the CLI prompt, by pressing Ctrl+Alt+F1. + +#. Logout and re-login. + +#. What is your present working directory, once you login? + +#. List all the files present in your current working directory. + +#. Navigate to the ``Desktop`` directory. If such a directory is not + present create one. + +#. Navigate back to the ``home`` directory. + +#. Create a directory called ``ult`` inside another directory called + ``sees``. Create both the directories in a single command. + +#. What would be your present working directory after doing the + following? + + :: + + cd ~/sees/./../ + +#. Use the touch command to create a file with your name in the + ``ult`` folder. + +#. Remove the file you created in the previous step. + +#. Navigate to your home directory and remove the directory + ``sees``. Use ``rm`` command. + +#. Re-create the directories ``sees`` and ``ult`` again. Now, remove + them using the ``rmdir`` command. Use ``man`` or ``--help``, if + required. + +#. Create a file with your first-name in your home directory and copy + it to ``sees/ult``. + +#. Copy the file again, but this time, ensure that ``cp`` checks if + such a file doesn't already exist. + +#. Copy the directory ``sees`` to the directory ``sttp``. + +#. Rename directory ``sttp`` with your name. + +#. Create a file ``test`` and modify its permission for user and group + to ``execute``. + +#. For the same ``test`` file, change mode to ``r,w,x`` for + all(user,group,others). + +#. Change ownership of the file ``test`` to some other user (if exists). + +#. Count the number of files (files, sub-directories, etc.) in a directory. + +#. Create a new file ``alice.txt`` by concatenating the first 30 lines + and the last 40 lines of ``wonderland.txt``. + +#. Show the lines from 10 to 20 of ``primes.txt`` + +#. Concatenate the content of ``foo.txt`` and ``bar.txt`` in a single + ``foobar.txt`` but with the ``source:wikipedia`` line appearing only + once, at the end of the file. + +Session-2 +--------- + +0. Read through the section ``REGULAR EXPRESSIONS`` in ``man grep`` + +#. Read through in ``man expr`` + +#. grep the marks of the students who scored above 75 in atleast one + subject. + +#. grep the marks of all the students whose names begin with an 's' + +#. grep the marks of all the students whose names begin with + consonants. + +#. change the results.sh script to accept the input files also as + arguments. + +#. Write a shell script that will take a filename as input and check + if it is executable. + +#. Modify the script in the previous step, to remove the execute + permissions, if the file is executable. + +#. Write a shell script to remove all executable files from a + directory, when a directory is given as argument. + +#. List all the years between 2001 and 2099 which have 5 Fridays, + Saturdays and Sundays in the month of July. Hint: ``man cal`` + +#. Generate frequency list of all the commands you have used, and show + the top 5 commands along with their count. (Hint: ``history`` command + will give you a list of all commands used.) + +#. generate a word frequency list for ``wonderland.txt``. Hint: use + ``grep``, ``tr``, ``sort``, ``uniq`` (or anything else that you want) + +#. **Print the middle line of a file**. + diff --git a/lecture_notes/ult/handout.rst b/lecture_notes/ult/handout.rst new file mode 100644 index 0000000..5ef762a --- /dev/null +++ b/lecture_notes/ult/handout.rst @@ -0,0 +1,2247 @@ +Introducing Linux +================= + +Linux (sometimes called GNU/Linux) is a Free and Open Source Operating +System that is inspired by Unix and runs on a variety of hardware +platforms. + +Free + Free as in Freedom or Free Speech, not Free Beer. + +Open-source + licensed to permit modifications and redistribution of its source code. + +Linux is a modular operating system, with it's basic design based on the +principles established in Unix. It consists of an important and central +piece called the Linux kernel, which, manages system resources like process +control, networking, peripherals and file system access. This is +complemented by the application software, written on top of the kernel that +give the higher level functionality that facilitate the user to carry out +various tasks. + +Why Linux? +---------- + +Free as in Free Beer + GNU/Linux can be downloaded in its entirety from the Internet completely + for free. No registration fees, no costs per user, free updates, and + freely available source code in case you want to change the behavior of + your system. + +Secure & versatile + The security model used in Linux is based on the UNIX idea of security, + which is known to be robust and of proven quality. Also, there are no + viruses in the GNU/Linux world. + +Why Linux for Scientific Computing? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Free as in Free Speech + You can share your operating system and the libraries that you are using + with your co-workers, without any headaches of licensing. Also, you can + study and improve the implementation of various libraries that you may + use for your work + +Tools for Scientific computing + There are a host of tools and libraries, written by various (groups of) + people that are useful in day-to-day scientific computing work. You have + the benefit of standing on the shoulders of giants. + +Keeps on running + GNU/Linux distributions are very stable and known for their up-time. You + don't have the fear of losing your computational work, due to system + crashes. + +Parallel & Distributed computing + It is pretty easy to build your own cluster with GNU/Linux and there are + host of libraries for parallel and distributed computing that work with + GNU/Linux. + + +Reading Exercises +----------------- + + 1. In the Beginning was the Command Line -- Neal Stephenson + #. Linux -- Wikipedia + #. GNU/Linux naming controversy -- Wikipedia + +Getting Started +=============== + + +Logging in +---------- + +Let's begin with logging into our system. The GNU/Linux OS supports +multiple users and each user logs in with his/her user-name and password. +After the machine boots up, the OS prompts you for a user-name and +password. You can log-in once you provide your authentication details. + +It is a popular misconception that GNU/Linux doesn't have a GUI (Graphical +user interface). It does have a fully functional GUI, but for the purpose +of this course we shall start with using the CLI (Command line interface). +Once your system has booted up, hit ``Ctrl + Alt + F1`` to switch to the +command line interface. + +You can log out using the ``logout`` command. + +Where am I? +----------- + +Now that we have logged in, where are we? Where did we get in? + +To find out the present working directory, we use the ``pwd`` command. + +:: + + $ pwd + /home/user + +What is in there? +----------------- + +To see what is in the current directory, we use the ``ls`` command. It +gives us a list of all the files in our present working directory. + +:: + + $ ls + jeeves.rst psmith.html blandings.html Music + +``ls`` command takes the directory, in which we want to see the list of +files present, as an argument. To see all the files present in the +``Music`` directory, we say + +:: + + $ ls Music + one.mp3 two.mp3 three.mp3 + +Note that everything in GNU/Linux and the Unix world is case sensitive. For +example if we had said ``ls music`` instead of ``ls Music``, we would get +an error ``No such file or directory``. + +New folders +----------- + +As you can see, our home folder has two html files one rst file and a +directory for Music. What if we wanted the files to be more organized? Say, +we would like to put all our work during this course in a separate +directory. Let us now create a directory ``sees`` by saying + +:: + + $ mkdir sees + +Again, note that we are using all small case letters. ``sees`` is different +from ``Sees`` or ``SEES``. Type ``ls`` to see that a new directory has been +created. + +:: + + $ ls + +Also, note that special characters need to be escaped. For example if we +wanted to create a directory with the name ``software engineering``, we do +it either as + +:: + + $ mkdir software\ engineering + +or as + +:: + + $ mkdir "software engineering" + +But it is generally a practice to use hyphens or underscores instead of +spaces in filenames and directory names. + +In modern GNU/Linux filesystems all characters except the forward slash are +allowed. + +Moving around +------------- + +Now that we have created our directory ``sees``, let us make it our present +working directory by moving into it. We use the ``cd`` command for this +purpose. + +:: + + $ cd sees + $ pwd + /home/user/sees/ + +This could alternately have been written as ``cd ./sees``. The dot in the +beginning specifies that we are specifying the path, relative to the +present working-directory. + +To go up the directory structure, we use ``..``. Typing + +:: + + $ cd .. + +in the ``sees`` directory will take us back to the home directory. + +What will happen if we type ``cd ..`` in the home folder? We go to the +``/home`` directory. + +All this while, we have been using what are called relative paths, to +specify the path. We could alternatively use the absolute path, which give +the whole path, starting with a /. The absolute path of the ``sees`` +directory is, ``/home/user/sees/``. + +New files +--------- + +Now that we have seen how to create a new empty directory and navigate into +it, let us create a new blank file. We use the ``touch`` command for this. + +:: + + $ pwd + /home/user + $ cd sees + $ touch first + +This creates a file named touch in our present working directory. Use the +``ls`` command to see that the file has been created. + +:: + + $ ls + first + + +Getting Help +============ + +What does a command do? +----------------------- + +To get a quick description of the command, we could use the ``whatis`` +command. It gives a short one-line description of the command that is +passed as an argument to it. For instance let's see what is the ``touch`` +command that we just saw. + +:: + + $ whatis touch + touch (1) - change file timestamps + +Now, what does it mean by change file timestamps? We used it to create a +file, just a while ago. To get a more detailed description of the command, +we use the ``man`` command. + +:: + + $ man touch + +This shows the ``man`` (short for "manual pages") page of the command. This +page gives a detailed description of the command. We can see that the +``touch`` command has a whole host of options that can be passed to it. +Every command in Linux has such a list of options that can be passed to the +command to do specific tasks. Hit the ``q`` key to quit the ``man`` page. + +To see the manual on man itself do + +:: + + $ man man + +Using additional options +------------------------ + +As you may have observed, often the ``man`` page is a bit too much for +quickly cross checking what option to use for a specific task. For this +kind of quick look-up, most of the commands come with a -h or --help +option. This gives a brief description of the options available for that +command. + +Let us look at using a couple of useful options that we can pass to +commands that we have already see. + +:: + + $ ls -R + +This lists out all the files in the sub-tree of the current directory, +recursively. + +When you wish to create a new directory deep inside a directory structure, +using a ``-p`` option with the ``mkdir`` command would be useful. For +example, if we wish to create a folder ``scripts`` inside the directory +``linux-tools`` inside the directory ``sees``, we could simply say, + +:: + + $ pwd + /home/user/ + $ mkdir -p sees/linux-tools/scripts + +This will create the scripts directory, inside the required directory +structure, creating any other new directory required, to maintain the tree +structure. + +Searching for a command +----------------------- + +Let's now say, we wish to remove a directory or a file. How do we find out +what command to use? We use the ``apropos`` command to search for commands +based on their descriptions. To search for the command to remove a +file/directory say, + +:: + + $ apropos remove + +This gives us a whole list of commands that have the word ``remove``, in +their description. Looking through the list tells us that ``rm`` or +``rmdir`` is the command to use. + + +Basic File Handling +=================== + +Removing files +-------------- + +``rm`` is used to delete files. + +Here's example to remove a file named "foo" from a directory, + +:: + + $ rm foo + +Note that, as such, ``rm`` works only for files and not for directories. +For instance, if you try to remove a directory named ``bar``, + +:: + + $ rm bar + +we get an error saying, cannot remove `bar`: Is a directory. But ``rm`` +takes additional arguments which can be used to remove a directory and all +of it's content, including sub-directories. + +:: + + $ rm -r bar + +removes the directory ``bar`` and all of it's content including +sub-directories, recursively. The ``-r`` stands for recursive. + +A function called ``rmdir`` is also available, to remove directories, but +we shall not look into it. + +Copying Files +------------- + +Let's say we wish to copy a file, ``foo`` from ``sees/linux-tools/scripts`` to +``sees/linux-tools``, how would we do it? + +:: + + $ pwd + /home/user/sees/ + + $ cp linux-tools/scripts/foo linux-tools/ + +In general, + +:: + + $ cp SourceFile TargetLocation + +Note, that we haven't changed the name of the file name at the target +location. We could have done that by specifying a new filename at the +target location. + +:: + + $ cp linux-tools/scripts/foo linux-tools/bar + +This copies the file ``foo`` to the new location, but with the new name, +``bar``. + +So, ``cp`` is the command to copy a file from one place to another. The +original file remains unchanged, and the new file may have the same or a +different name. + +But, what would have happened if we had a file named ``bar`` already at the +new location? Let's try doing the copy again, and see what happens. + +:: + + $ cp linux-tools/scripts/foo linux-tools/bar + +We get no error message, what happened? ``cp`` actually overwrites files. +In this case, it's not a problem since, we just re-copied the same content, +but in general it could be a problem, and we could lose data. To prevent +this, we use the ``-i`` flag with ``cp``. + +:: + + $ cp -i linux-tools/scripts/foo linux-tools/bar + cp: overwrite `bar'? + +We are now prompted, whether the file should be over-written. To over-write +say ``y``, else say ``n``. + +Now, let's try to copy the directory ``sees`` to a new directory called +``course``. How do we do it? + +:: + + $ cd /home/user + $ cp -i sees course + cp: omitting directory `sees/' + +``cp`` refuses to copy the directory ``sees``. We use the option ``-r`` +(recursive) to copy the directory and all it's content. + +:: + + $ cd /home/user + $ cp -ir sees course + + +Moving Files +------------ + +What if we want to move files, instead of copying them? One way to go about +it, would be to ``cp`` the file to the new location and ``rm`` the old +file. + +But, there's a command that does this for you, ``mv`` (short for move). It +can move files or directories. It also takes the ``-i`` option to prompt +before overwriting. + +:: + + $ cd /home/user + $ mv -i sees/ course/ + +What happened? Why didn't we get any prompt? Did course get overwritten? + +:: + + $ ls course + +We can see that the ``sees`` directory has been inserted as sub-directory +of the ``course`` directory. The move command doesn't over-write +directories, but the ``-i`` option is useful when moving files around. + +A common way to rename files (or directories), is to copy a file (or a +directory) to the same location, with a new name. + +:: + + $ mv sees/linux-tools sees/linux + +will rename the ``linux-tools`` directory to just ``linux``. + + +Linux File Hierarchy & Permissions and ownership +================================================ + +While moving around our files and directories, we have been careful to stay +within the ``/home/`` directory, but if you were curious, you may have +ventured out and seen that there are a lot of other directories. Let us +take this opportunity to understand a few things about the linux file +hierarchy and file permissions. + +:: + + $ cd / + +The ``/`` directory is called the root directory. All the files and +directories, (even if they are on different physical devices) appear as +sub-directories of the root directory. + +:: + + $ ls + +You can see the various directories present at the top most level. Below is +a table that briefly describes, what is present in each of these +directories and what their function is. + ++---------------+------------------------------------------------+ +| Directory | Description | ++===============+================================================+ +| / | Primary hierarchy root and root directory of | +| | the entire file system hierarchy. | ++---------------+------------------------------------------------+ +| /bin/ | Essential command binaries that need to be | +| | available in single user mode; for all users, | +| | e.g., *cat*, *ls*, *cp*. | ++---------------+------------------------------------------------+ +| /boot/ | Boot loader files, e.g., *kernels*, *initrd*; | +| | often a separate partition. | ++---------------+------------------------------------------------+ +| /dev/ | Essential devices, e.g., /dev/null | ++---------------+------------------------------------------------+ +| /etc/ | Host-specific system-wide configuration files | +| | (the name comes from *et cetera*) | ++---------------+------------------------------------------------+ +| /home/ | User's home directories, containing saved | +| | files, personal settings, etc.; often a | +| | separate partition. | ++---------------+------------------------------------------------+ +| /lib/ | Libraries essential for the binaries in | +| | */bin/* and */sbin/* | ++---------------+------------------------------------------------+ +| /media/ | Mount points for removable media such as | +| | CD-ROMs, external hard disks, USB sticks, etc. | ++---------------+------------------------------------------------+ +| /mnt/ | Temporarily mounted file systems | ++---------------+------------------------------------------------+ +| /opt/ | Optional application software packages | ++---------------+------------------------------------------------+ +| /proc/ | Virtual filesystem documenting kernel and | +| | process status as text files; e.g., uptime, | +| | network. In Linux, corresponds to a *Procfs* | +| | mount. | ++---------------+------------------------------------------------+ +| /root/ | Home directory for the root user | ++---------------+------------------------------------------------+ +| /sbin/ | Essential system binaries; e.g., *init*, | +| | *route*, *mount*. | ++---------------+------------------------------------------------+ +| /srv/ | Site-specific data which is served by the | +| | system. | ++---------------+------------------------------------------------+ +| /tmp/ | Temporary files. Often not preserved between | +| | system reboots. | ++---------------+------------------------------------------------+ +| /usr/ | Secondary hierarchy for read-only user data; | +| | contains the majority of (multi-)user | +| | utilities and applications. | ++---------------+------------------------------------------------+ +| /var/ | Variable files - files whose content is | +| | expected to continually change during normal | +| | operation of the system - such as logs, spool | +| | files, and temporary e-mail files. | +| | Sometimes a separate partition. | ++---------------+------------------------------------------------+ + + +Note that some of these directories may or may not be present on your Unix +system depending on whether certain subsystems, such as the X Window +System, are installed. + +For more information, it is recommended that you look at the ``man`` page +of ``hier``. + +:: + + $ man hier + +Permissions and Access control +------------------------------ + +Let us now look at file permissions. Linux is a multi-user environment and +allows users to set permissions to their files to allow only a set of +people to read or write it. Similarly, it is not "safe" to allow system +files to be edited by any user. All this access control is possible in +Linux. + +To start, in the root directory, say, + +:: + + $ ls -l + +You again get a list of all the sub-directories, but this time with a lot +of additional information. Let us try and understand what this output says. + +:: + + drwxr-xr-x 5 root users 4096 Jan 21 20:07 home + +The first column denotes the type and the access permissions of the file. +The second is the number of links. The third and fourth are the owner and +group of the file. The next field is the size of the file in bytes. The +next field is the date and time of modification and the last column is the +file name. + +We shall look at the permissions of the file now, ie., the first column of +the output. + +The first character in the first column specifies, whether the item is a +file or a directory. Files have a ``-`` as the first character and +directories have a ``d``. + +The next 9 characters define the access permissions of the file. Before +looking at it, we need to briefly study groups and users and ownership. + +Each file in the Linux filesystem is associated with a user and a group. +The user and the group of the file can be seen in the third and the fourth +columns of the output of ``ls -l`` command. The third column is the user, +and is usually the person who has created the file. A group is simply a +group of users. Users can be added or removed from groups, but doing that +is out of the scope of this course. This brief introduction to users and +groups is enough to go ahead and understand access permissions. + +We already know what the first character in the first column (in the output +of ``ls -l``) is for. The rest of the 9 characters are actually sets of 3 +characters of each. The first set of 3 characters defines the permissions +of the user, the next 3 is for the group and the last three is for others. +Based on the values of these characters, access is provided or denied to +files, to each of the users. + +So, what does each of the three characters stand for? Let's suppose we are +looking at the set, corresponding to the permissions of the user. In the +three characters, the first character can either be an ``r`` or a ``-``. +Which means, the user can either have the permissions to read the file or +not. If the character is ``r``, then the user has the permissions to read +the file, else not. Similarly, ``w`` stands for write permissions and +decides whether the user is allowed to write to the file. ``x`` stands for +execute permissions. You cannot execute a file, if you do not have the +permissions to execute it. + +Similarly, the next set of characters decides the same permissions for the +members of the group, that the file is associated with. The last set of +characters defines these permissions for the users, who are neither owners +of the file nor in the group, with which the file is associated. + +Changing the permissions +------------------------ + +Now, it's not as if these permissions are set in stone. If you are the +owner of a file, you can change the permissions of a file, using the +``chmod`` command. + +Let's say, we wish to give the execute permissions for a file, to both the +user and the group, how do we go about doing it? To be more explicit, given +a file ``foo.sh``, with the permissions flags as ``-rw-r--r--``, change it +to ``-rwxr-xr--``. + +The following command does it for us, + +:: + + $ chmod ug+x foo.sh + $ ls -l foo.sh + +As you can see, the permissions have been set to the required value. But +what did we exactly do? Let us try and understand. + +Symbolic modes +~~~~~~~~~~~~~~ + +In the command above, the parameter ``ug+x`` is the mode parameter to the +``chmod`` command. It specifies the changes that need to be made to the +permissions of the file ``foo.sh``. + +The ``u`` and ``g`` stand for the user and group, respectively. The ``x`` +stands for the execute permission and the ``+`` stands for adding the +specified permission. So, essentially, we are asking ``chmod`` command to +add the execute permission for the user and group. The permission of others +will remain unchanged. + +The following three tables give the details of the class, the operator and +the permissions. + ++--------------+--------+---------------------------------------------+ +| Reference | Class | Description | ++==============+========+=============================================+ +| u | user | the owner of the file | ++--------------+--------+---------------------------------------------+ +| g | group | users who are members of the file's group | ++--------------+--------+---------------------------------------------+ +| o | others | users who are not hte owner of the file or | +| | | members of the group | ++--------------+--------+---------------------------------------------+ +| a | all | all three of the above; is the same as *ugo*| ++--------------+--------+---------------------------------------------+ + ++--------------+------------------------------------------------------+ +| Operator | Description | ++==============+======================================================+ +| + | adds the specified modes to the specified classes | ++--------------+------------------------------------------------------+ +| - | removes the specified modes from the specified | +| | classes | ++--------------+------------------------------------------------------+ +| = | the modes specified are to be made the exact modes | +| | for the specified classes | ++--------------+------------------------------------------------------+ + ++-----+--------------+------------------------------------------------+ +|Mode | Name | Description | ++=====+==============+================================================+ +| r | read | read a file or list a directory's contents | ++-----+--------------+------------------------------------------------+ +| w | write | write to a file or directory | ++-----+--------------+------------------------------------------------+ +| x | execute | execute a file or recurse a directory tree | ++-----+--------------+------------------------------------------------+ + +So, if we wished to add the execute permission to all the users, instead of +adding it to just the user and group, we would have instead said + +:: + + $ chmod a+x foo.sh + +or + +:: + + $ chmod ugo+x foo.sh + + +To change the permissions of a directory along with all of its +sub-directories and files, recursively, we use the ``-R`` option. + +For instance if we wished to remove the read permissions of a file from all +users except the owner of the file, we would say, + + +:: + + $ chmod go-r bar.txt + +It is important to note that the permissions of a file can only be changed +by a user who is the owner of a file or the superuser. (We shall talk about +the superuser in the next section) + + +Changing Ownership of Files +--------------------------- + +What if we wish to change the ownership of a file? The ``chown`` command is +used to change the owner and group. + +By default, the owner of a file (or directory) object is the user that +created it. The group is a set of users that share the same access +permissions (i.e., read, write and execute). + +For instance, to change the user and the group of the file +``wonderland.txt`` to ``alice`` and ``users``, respectively, we say. + + $ chown alice:users wonderland.txt + +What does it say? We get an error saying, the operation is not permitted. +We have attempted to change the ownership of a file that we own, to a +different user. Logically, this shouldn't be possible, because, this can +lead to problems, in a multi-user system. + +Only the superuser is allowed to change the ownership of a file from one +user to another. The superuser or the ``root`` user is the only user +empowered to a certain set of tasks and hence is called the superuser. The +command above would have worked, if you did login as the superuser and +then changed the ownership of the file. + +We shall end our discussion of the Linux hierarchy and file permissions +here. Let us look at working with text, files and the role of the command +shell in the next section. + +Looking at files +================ + +cat +--- + +The ``cat`` command is the most commonly used command to display the +contents of files. To view the contents of a file, say, ``foo.txt``, we +simply say, + +:: + + $ cat foo.txt + +The contents of the file are shown on the terminal. + +The cat command could also be used to concatenate the text of multiple +files. (It's name actually comes from there). Say, we have two files, +``foo.txt`` and ``bar.txt``, + +:: + + $ cat foo.txt bar.txt + +shows the output of both the files concatenated on the standard output. + +But if we had a long file, like ``wonderland.txt``, the ouptut of ``cat`` +command is not convenient to read. Let's look at the ``less`` command which +turns out to be more useful in such a case. + + +less +---- + +``less `` allows you to view the contents of a text file one screen at a +time. + +:: + + $ less wonderland.txt + +will give show us the file, one screen at a time. + +``less`` has a list of commands that it allows you to use, once you have +started viewing a file. A few of the common ones have been listed below. + + * q: Quit. + + * [Arrows]/[Page Up]/[Page Down]/[Home]/[End]: Navigation. + + * ng: Jump to line number n. Default is the start of the file. + + * /pattern: Search for pattern. Regular expressions can be used. + + * h: Help. + +wc +-- + +Often we just would like to get some statistical information about the +file, rather than viewing the contents of the file. The ``wc`` command +prints these details for a file. + +:: + + $ wc wonderland.txt + +The first number is the number of lines, the second is the number of words +and the third is the number of characters in the file. + +head & tail +----------- + +Let us now look at a couple of commands that let you see parts of files, +instead of the whole file. ``head`` and ``tail`` let you see parts of +files, as their names suggest, the start and the end of a file, +respectively. + +:: + + $ head wonderland.txt + +will print the first 10 lines of the file. Similarly tail will print the +last 10 lines of the file. If we wish to change the number of lines that we +wish to view, we use the option ``-n``. + +:: + + $ head -n 1 wonderland.txt + +will print only the first line of the file. Similarly, we could print only +the last line of the file. + +The most common use of the tail command is to monitor a continuously +changing file, for instance a log file. Say you have a process running, +which is continuously logging it's information to a file, for instance the +logs of the system messages. + +:: + + $ tail -f /var/log/dmesg + +This will show the last 10 lines of the file as expected, but along with +that, start monitoring the file. Any new lines added at the end of the +file, will be shown. To interrupt, tail while it is monitoring, hit +``Ctrl-C``. Ctrl-C is used to stop any process that is running from your +current shell. + +cut & paste +----------- + +We looked at a couple of functions that allow you to view a part of files, +line-wise. We shall now look at a couple of commands that allow you to look +at only certain sections of each line of a file and merge those parts. + +Let's take the ``/etc/passwd`` file as our example file. It contains +information about each user of the system. + +:: + + root:x:0:0:root:/root:/bin/bash + bin:x:1:1:bin:/bin:/bin/false + daemon:x:2:2:daemon:/sbin:/bin/false + mail:x:8:12:mail:/var/spool/mail:/bin/false + ftp:x:14:11:ftp:/srv/ftp:/bin/false + http:x:33:33:http:/srv/http:/bin/false + +Let us look at only the first, fifth, sixth and the last columns. The first +column is the user name, the fifth column is the user info, the sixth +column is the home folder and the last column is the path of the shell +program that the user uses. + +Let's say we wish to look at only the user names of all the users in the +file, how do we do it? + +:: + + $ cut -d : -f 1 /etc/passwd + +gives us the required output. But what are we doing here? + +The first option ``-d`` specifies the delimiter between the various fields in +the file, in this case it is the semicolon. If no delimiter is specified, +the TAB character is assumed to be the delimiter. The ``-f`` option specifies, +the field number that we want to choose. + +You can print multiple fields, by separating the field numbers with a +comma. + +:: + + $ cut -d : -f 1,5,7 /etc/passwd + +prints only the first, fifth and the seventh fields. + +Instead of choosing by fields, ``cut`` also allows us to choose on the +basis of characters or bytes. For instance, we could get the first 4 +characters of all the entries of the file, ``/etc/passwd`` + +:: + + $ cut -c 1-4 /etc/passwd + +The end limits of the ranges can take sensible default values, if they are +left out. For example, + +:: + + $ cut -c -4 /etc/passwd + +gives the same output as before. If the start position has not been +specified, it is assumed to be the start of the line. Similarly if the end +position is not specified, it is assumed to be the end of the line. + +:: + + $ cut -c 10- /etc/passwd + +will print all the characters from the 10th character up to the end of the +line. + +Let us now solve the inverse problem. Let's say we have two columns of data +in two different files, and we wish to view them side by side. + +For instance, given a file containing the names of students in a file, and +another file with the marks of the students, we wish to view the contents, +side by side. ``paste`` command allows us to do that. + +Contents of students.txt + +:: + + Hussain + Dilbert + Anne + Raul + Sven + +Contents of marks.txt + +:: + + 89 92 85 + 98 47 67 + 67 82 76 + 78 97 60 + 67 68 69 + +:: + + $ paste students.txt marks.txt + + $ paste -s students.txt marks.txt + + +The first command gives us the output of the two files, next to each other +and the second command gives us the output one below the other. + +Now, this problem is a bit unrealistic because, we wouldn't have the marks +of students in a file, without any information about the student to which +they belong. Let's say our marks file had the first column as the roll +number of the student, followed by the marks of the students. What would we +then do, to get the same output that we got before? + +Essentially we need to use both, the ``cut`` and ``paste`` commands, but +how do we do that? That brings us to the topic of Redirection and Piping. + +The Command Shell +================= + +Redirection and Piping +---------------------- + +Let's say the contents of ``marks1.txt`` are as follows, + +:: + + 5 89 92 85 + 4 98 47 67 + 1 67 82 76 + 2 78 97 60 + 3 67 68 69 + +The solution would be as below + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt - + +or + +:: + + $ cut -d " " -f 2- marks1.txt > /tmp/m_tmp.txt + $ paste -d " " students.txt m_tmp.txt + + +Let's first try to understand the second solution, which is a two step +solution. Later, we shall look at the first solution. + +Redirecting +~~~~~~~~~~~ + +The standard output (stdout), in general, streams (or goes) to the display. +Hence, the output of the commands that we type, come out to the display. +This may not always be what we require. + +For instance, in the solution above, we use the cut command and get only +the required columns of the file and write the output to a new temporary +file. The ``>`` character is used to state that we wish to redirect the +output, and it is followed by the location to which we wish to redirect. + +:: + + $ command > file1 + +In general, this creates a new file at the specified location, to which the +output is written. But, if we wish to append the output to an existing +file, we use ``>>``. + +Similarly, the standard input (stdin) is assumed to be from the keyboard. +Instead we could redirect the input from a file. + +:: + + $ command < file1 + +The input and the output redirection could be combined in a single command. + +:: + + $ command < infile > outfile + + +There is actually a third kind of standard stream, called the Standard +error (stderr). Any error messages that you get, are coming through this +stream. Like ``stdout``, ``stderr`` also streams to the display, by default +but it could be redirected to a file, as well. + +For instance, let's introduce an error into the ``cut`` command used +before. We change the ``-f`` option to ``-c`` + +:: + + $ cut -d " " -c 2- marks1.txt > /tmp/m_tmp.txt + +This prints an error that says the delimiter option should be used with the +fields option only, and you can verify that the ``m_tmp.txt`` file is +empty. We can now, redirect the ``stderr`` also to a file, instead of +showing it on the display. + +:: + + $ cut -d " " -f 2- marks1.txt 1> /tmp/m_tmp.txt 2> /tmp/m_err.txt + +The above command redirects all the errors to the ``m_err.txt`` file +and the output to the ``m_tmp.txt`` file. When redirecting, 1 stands +for ``stdout`` and 2 stands for ``stderr``. That brings us to the end of +the discussion on redirecting. + +The second command in the solution of the problem is trivial to understand. +:: + + $ paste -d " " students.txt m_tmp.txt + +So, in two steps we solved the problem of getting rid of the roll numbers +from the marks file and displaying the marks along with the names of the +students. Now, that we know how to redirect output, we could choose to +write the output to a file, instead of showing on the display. + +Piping +~~~~~~ + +Let us now look at the first solution. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt - + +First of all, the hyphen at the end is to ask the paste command to read the +standard input, instead of looking for a FILE. The ``man`` page of ``paste`` +command gives us this information. + +Now, what is happening with the ``cut`` command. It is a normal ``cut`` +command, if we looked at the command only up to the ``|`` character. So, +the ``|`` seems to be joining the commands in some way. + +Essentially, what we are doing is, to redirect the output of the first +command to the ``stdin`` and the second command takes input from the +``stdin``. + +More generally, + +:: + + $ command1 | command2 + +executes ``command1`` and sends it's output to the ``stdin``, which is then +used as the input for the ``command2``. This activity is commonly called +piping, and the character ``|`` is called a pipe. + +This is roughly equivalent to using two redirects and a temporary file + +:: + + $ command1 > tempfile + $ command2 < tempfile + $ rm tempfile + +Also, given that a pipe is just a way to send the output of the command to +the ``stdin``, it should be obvious, to you that we can use a chain of +pipes. Any number of commands can be piped together and you need not be +restricted to two commands. + +Using piping and redirection, we can do a whole bunch of complex tasks +combined with the commands we have already looked at, and other commands +that we are going to look at. + +Features of the Shell +--------------------- + +The Bash shell has some nice features, that make our job of using the shell +easier and much more pleasant. We shall look at a few of them, here. + +Tab-completion +~~~~~~~~~~~~~~ + +Bash provides the feature of tab completion. What does tab completion mean? +When you are trying to type a word, bash can complete the word for you, +if you have entered enough portion of the word (to complete it +unambiguously) and then hit the tab key. + +If on hitting the tab key, the word doesn't get completed, either the word +doesn't exist or the word cannot be decided unambiguously. If the case is +the latter one, hitting the tab key a second time, will list the +possibilities. + +Bash provides tab completion for the following. + + 1. File Names + 2. Directory Names + 3. Executable Names + 4. User Names (when they are prefixed with a ~) + 5. Host Names (when they are prefixed with a @) + 6. Variable Names (when they are prefixed with a $) + +For example, + +:: + + $ pas<TAB> + $ $PA<TAB> + $ ~/<TAB><TAB> + +History +~~~~~~~ + +Bash also saves the history of the commands you have typed. So, you can go +back to a previously typed command. Use the up and down arrow keys to +navigate in your bash history. + +:: + + $ <UP-ARROW> + +You can also search incrementally, for commands in your bash history. +``Ctrl-r`` search for the commands that you have typed before. But, note +that the number of commands saved in the history is limited, generally upto +a 1000 commands. + +:: + + $ <Ctrl-r> pas + + +Shell Meta Characters +~~~~~~~~~~~~~~~~~~~~~ + +Unix recognizes certain special characters, called "meta characters," as +command directives. The shell meta characters are recognized anywhere they +appear in the command line, even if they are not surrounded by blank space. +For that reason, it is safest to only use the characters A-Z, a-z, 0-9, and +the period, dash, and underscore characters when naming files and +directories on Unix. If your file or directory has a shell meta character +in the name, you will find it difficult to use the name in a shell command. + +The shell meta characters include: + +\ / < > ! $ % ^ & * | { } [ ] " ' ` ~ ; + + +As an example, + +:: + + $ ls file.* + +run on a directory containing the files file, file.c, file.lst, and myfile +would list the files file.c and file.lst. However, + +:: + + $ ls file.? + +run on the same directory would only list file.c because the ? only matches +one character, no more, no less. This can save you a great deal of typing +time. + +For example, if there is a file called +california_cornish_hens_with_wild_rice and no other files whose names begin +with 'c', you could view the file without typing the whole name by typing +this + +:: + + $ more c* + +because the c* matches that long file name. + +File-names containing metacharacters can pose many problems and should +never be intentionally created. + +More text processing +==================== + +``sort`` +-------- + +Let's continue with the previous problem of the students and their marks, +that we had. Let's say we wish to sort the output in the alphabetical order +of the names of the files. We can use the ``sort`` command for this +purpose. + +We just pipe the previous output to the ``sort`` command. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt -| sort + +Let's say we wished to sort the names, based on the marks in the first +subject (first column after the name). ``sort`` command also allows us to +specify the delimiter between the fields and sort the data on a particular +field. ``-t`` option is used to specify the delimiter and the ``-k`` option +is used to specify the field. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt -| sort -t " " -k 2 + +The above command give us a sorted output as required. But, it would be +nicer to have the output sorted in the reverse order. ``-r`` option allows +the output to be sorted in the reverse order and the ``-n`` option is used +to choose a numerical sorting. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt -| sort -t " " -k 2 -rn + +``grep`` +-------- + +While you are compiling the student marklist, Anne walks up to you and +wants to know her marks. You, being the kind person that you are, oblige. +But you do not wish to her to see the marks that others have scored. What +do you do? The ``grep`` command comes to your rescue. + +``grep`` is a command line text search utility. You can use it to search +for Anne and show her, what she scored. ``grep`` allows you to search for a +search string in files. But you could, like any other command, pipe the +output of other commands to it. So, we shall use the previous combination +of cut and paste that we had, to get the marks of students along with their +names and search for Anne in that. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | grep Anne + +This will give you only the line containing the word Anne as the output. +The grep command is by default case-sensitive. So, you wouldn't have got +the result if you had searched for anne instead of Anne. But, what if you +didn't know, whether the name was capitalized or not? ``grep`` allows you +to do case-insensitive searches by using the ``-i`` option. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | grep -i Anne + +Now, in another scenario, if you wished to print all the lines, which do +not contain the word Anne, you could use the ``-v`` option. + +:: + + $ cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | grep -iv Anne + +Grep allows you to do more complex searches, for instance searching for +sentences starting or ending with a particular pattern and regular +expression based searches. You shall learn about these, as a part of your +lab exercises. + +``tr`` +------ + +``tr`` is a command that takes as parameters two sets of characters, and +replaces occurrences of the characters in the first set with the +corresponding elements from the other set. It reads from the standard +output and writes to the standard output. + +For instance if you wished to replace all the lower case letters in the +students file with upper case, + +:: + + $ cat students.txt | tr a-z A-Z + +A common task is to remove empty newlines from a file. The ``-s`` flag +causes ``tr`` to compress sequences of identical adjacent characters in its +output to a single token. For example, + +:: + + $ tr -s '\n' '\n' + +replaces sequences of one or more newline characters with a single newline. + +The ``-d`` flag causes ``tr`` to delete all tokens of the specified set of +characters from its input. In this case, only a single character set +argument is used. The following command removes carriage return characters, +thereby converting a file in DOS/Windows format to the Unix format. + +:: + + $ cat foo.txt | tr -d '\r' > bar.txt + +The ``-c`` flag complements the first set of characters. + +:: + + $ tr -cd '[:alnum:]' + +therefore removes all non-alphanumeric characters. + +``uniq`` +-------- + +Suppose we have a list of items, say books, and we wish to obtain a list which names of all the books only once, without any duplicates. We use the ``uniq`` command to achieve this. + +:: + + Programming Pearls + The C Programming Language + The Mythical Man Month: Essays on Software Engineering + Programming Pearls + The C Programming Language + Structure and Interpretation of Computer Programs + Programming Pearls + Compilers: Principles, Techniques, and Tools + The C Programming Language + The Art of UNIX Programming + Programming Pearls + The Art of Computer Programming + Introduction to Algorithms + The Art of UNIX Programming + The Pragmatic Programmer: From Journeyman to Master + Programming Pearls + Unix Power Tools + The Art of UNIX Programming + +Let us try and get rid of the duplicate lines from this file using the ``uniq`` command. + +:: + + $ uniq items.txt + Programming Pearls + The C Programming Language + The Mythical Man Month: Essays on Software Engineering + Programming Pearls + The C Programming Language + Structure and Interpretation of Computer Programs + Programming Pearls + Compilers: Principles, Techniques, and Tools + The C Programming Language + The Art of UNIX Programming + Programming Pearls + The Art of Computer Programming + Introduction to Algorithms + The Art of UNIX Programming + The Pragmatic Programmer: From Journeyman to Master + Programming Pearls + Unix Power Tools + The Art of UNIX Programming + +Nothing happens! Why? The ``uniq`` command removes duplicate lines only when they are next to each other. So, we get a sorted file from the original file and work with that file, henceforth. + +:: + + $ sort items.txt | uniq + Compilers: Principles, Techniques, and Tools + Introduction to Algorithms + Programming Pearls + Structure and Interpretation of Computer Programs + The Art of Computer Programming + The Art of UNIX Programming + The C Programming Language + The Mythical Man Month: Essays on Software Engineering + The Pragmatic Programmer: From Journeyman to Master + Unix Power Tools + +``uniq -u`` command gives the lines which are unique and do not have any duplicates in the file. ``uniq -d`` outputs only those lines which have duplicates. The ``-c`` option displays the number of times each line occurs in the file. + +:: + + $ uniq -u items-sorted.txt + Compilers: Principles, Techniques, and Tools + Introduction to Algorithms + Structure and Interpretation of Computer Programs + The Art of Computer Programming + The Mythical Man Month: Essays on Software Engineering + The Pragmatic Programmer: From Journeyman to Master + Unix Power Tools + + $ uniq -dc items-sorted.txt + 5 Programming Pearls + 3 The Art of UNIX Programming + 3 The C Programming Language + +That brings us to the end of our discussion on text processing. Text +processing is an art and there is a lot more to it, than could have been +covered in this short introduction. But, we hope that the tools you learned +to use here, will help you solve a great deal of problems. + +Basic editing and editors +========================= + +vim +--- + +Vim is a very powerful editor. It has a lot of commands, and all of them +cannot be explained here. We shall try and look at a few, so that you can +find your way around in vim. + +To open a file in vim, we pass the filename as a parameter to the ``vim`` +command. If a file with that filename does not exist, a new file is +created. + +:: + + $ vim first.txt + +To start inserting text into the new file that we have opened, we need to +press the ``i`` key. This will take us into the *insert* mode from the +*command* mode. Hitting the ``esc`` key, will bring us back to the +*command* mode. There is also another mode of vim, called the *visual* mode +which will be discussed later in the course. + +In general, it is good to spend as little time as possible in the insert +mode and extensively use the command mode to achieve various tasks. + +To save the file, use ``:w`` in the command mode. From here on, it is +understood that we are in the command mode, whenever we are issuing any +command to vim. + +To save a file and continue editing, use ``:w FILENAME`` The file name is +optional. If you do not specify a filename, it is saved in the same file +that you opened. If a file name different from the one you opened is +specified, the text is saved with the new name, but you continue editing +the file that you opened. The next time you save it without specifying a +name, it gets saved with the name of the file that you initially opened. + +To save file with a new name and continue editing the new file, use ``:saveas FILENAME`` + +To save and quit, use ``:wq`` + +To quit, use ``:q`` + +To quit without saving, use ``:q!`` + +Moving around +~~~~~~~~~~~~~ + +While you are typing in a file, it is in-convenient to keep moving your +fingers from the standard position for typing to the arrow keys. Vim, +therefore, provides alternate keys for moving in the document. Note again +that, you should be in the command mode, when issuing any commands to vim. + +The basic cursor movement can be achieved using the keys, ``h`` (left), +``l`` (right), ``k`` (up) and ``j`` (down). + +:: + + ^ + k + < h l > + j + v + +Note: Most commands can be prefixed with a number, to repeat the command. +For instance, ``10j`` will move the cursor down 10 lines. + +Moving within a line +++++++++++++++++++++ + ++----------------------------------------+---------+ +| Cursor Movement | Command | ++========================================+=========+ +| Beginning of line | ``0`` | ++----------------------------------------+---------+ +| First non-space character of line | ``^`` | ++----------------------------------------+---------+ +| End of line | ``$`` | ++----------------------------------------+---------+ +| Last non-space character of line | ``g_`` | ++----------------------------------------+---------+ + +Moving by words and sentences ++++++++++++++++++++++++++++++ + ++------------------------------+---------+ +| Cursor Movement | Command | ++==============================+=========+ +| Forward, word beginning | ``w`` | ++------------------------------+---------+ +| Backward, word beginning | ``b`` | ++------------------------------+---------+ +| Forward, word end | ``e`` | ++------------------------------+---------+ +| Backward, word end | ``ge`` | ++------------------------------+---------+ +| Forward, sentence beginning | ``)`` | ++------------------------------+---------+ +| Backward, sentence beginning | ``(`` | ++------------------------------+---------+ +| Forward, paragraph beginning | ``}`` | ++------------------------------+---------+ +| Backward, paragraph beginning| ``{`` | ++------------------------------+---------+ + +More movement commands +++++++++++++++++++++++ + ++---------------------------------+------------+ +| Cursor Movement | Command | ++=================================+============+ +| Forward by a screenful of text | ``C-f`` | ++---------------------------------+------------+ +| Backward by a screenful of text | ``C-b`` | ++---------------------------------+------------+ +| Beginning of the screen | ``H`` | ++---------------------------------+------------+ +| Middle of the screen | ``M`` | ++---------------------------------+------------+ +| End of the screen | ``L`` | ++---------------------------------+------------+ +| End of file | ``G`` | ++---------------------------------+------------+ +| Line number ``num`` | ``[num]G`` | ++---------------------------------+------------+ +| Beginning of file | ``gg`` | ++---------------------------------+------------+ +| Next occurrence of the text | ``*`` | +| under the cursor | | ++---------------------------------+------------+ +| Previous occurrence of the text | ``#`` | +| under the cursor | | ++---------------------------------+------------+ + +Note: ``C-x`` is ``Ctrl`` + ``x`` + +The visual mode +~~~~~~~~~~~~~~~ + +The visual mode is a special mode that is not present in the original vi +editor. It allows us to highlight text and perform actions on it. All the +movement commands that have been discussed till now work in the visual mode +also. The editing commands that will be discussed in the future work on the +visual blocks selected, too. + +Editing commands +~~~~~~~~~~~~~~~~ + +The editing commands usually take the movements as arguments. A movement is +equivalent to a selection in the visual mode. The cursor is assumed to have +moved over the text in between the initial and the final points of the +movement. The motion or the visual block that's been highlighted can be +passed as arguments to the editing commands. + ++-------------------------+---------+ +| Editing effect | Command | ++=========================+=========+ +| Cutting text | ``d`` | ++-------------------------+---------+ +| Copying/Yanking text | ``y`` | ++-------------------------+---------+ +| Pasting copied/cut text | ``p`` | ++-------------------------+---------+ + +The cut and copy commands take the motions or visual blocks as arguments +and act on them. For instance, if you wish to delete the text from the +current text position to the beginning of the next word, type ``dw``. If +you wish to copy the text from the current position to the end of this +sentence, type ``y)``. + +Apart from the above commands, that take any motion or visual block as an +argument, there are additional special commands. + ++----------------------------------------+---------+ +| Editing effect | Command | ++========================================+=========+ +| Cut the character under the cursor | ``x`` | ++----------------------------------------+---------+ +| Replace the character under the | ``ra`` | +| cursor with ``a`` | | ++----------------------------------------+---------+ +| Cut an entire line | ``dd`` | ++----------------------------------------+---------+ +| Copy/yank an entire line | ``yy`` | ++----------------------------------------+---------+ + +Note: You can prefix numbers to any of the commands, to repeat them. + +Undo and Redo +~~~~~~~~~~~~~ +You can undo almost anything using ``u``. + +To undo the undo command type ``C-r`` + +Searching and Replacing +~~~~~~~~~~~~~~~~~~~~~~~ + ++-----------------------------------------+---------+ +| Finding | Command | ++=========================================+=========+ +| Next occurrence of ``text``, forward |``\text``| ++-----------------------------------------+---------+ +| Next occurrence of ``text``, backward |``?text``| ++-----------------------------------------+---------+ +| Search again in the same direction | ``n`` | ++-----------------------------------------+---------+ +| Search again in the opposite direction | ``N`` | ++-----------------------------------------+---------+ +| Next occurrence of ``x`` in the line | ``fx`` | ++-----------------------------------------+---------+ +| Previous occurrence of ``x`` in the line| ``Fx`` | ++-----------------------------------------+---------+ + ++---------------------------------------+------------------+ +| Finding and Replacing | Command | ++=======================================+==================+ +| Replace the first instance of ``old`` |``:s/old/new`` | +| with ``new`` in the current line. | | ++---------------------------------------+------------------+ +| Replace all instances of ``old`` |``:s/old/new/g`` | +| with ``new`` in the current line. | | ++---------------------------------------+------------------+ +| Replace all instances of ``old`` |``:s/old/new/gc`` | +| with ``new`` in the current line, | | +| but ask for confirmation each time. | | ++---------------------------------------+------------------+ +| Replace the first instance of ``old`` |``:%s/old/new`` | +| with ``new`` in the entire file. | | ++---------------------------------------+------------------+ +| Replace all instances of ``old`` |``:%s/old/new/g`` | +| with ``new`` in the entire file. | | ++---------------------------------------+------------------+ +| Replace all instances of ``old`` with |``:%s/old/new/gc``| +| ``new`` in the entire file but ask | | +| for confirmation each time. | | ++---------------------------------------+------------------+ + +SciTE +----- + +SciTE is a *source code* editor, that has a feel similar to the commonly +used GUI text editors. It has a wide range of features that are extremely +useful for a programmer, editing code. Also it aims to keep configuration +simple, and the user needs to edit a text file to configure SciTE to +his/her liking. + +Opening, Saving, Editing files with SciTE is extremely simple and trivial. +Knowledge of using a text editor will suffice. + +SciTE can syntax highlight code in various languages. It also has +auto-indentation, code-folding and other such features which are useful +when editing code. + +SciTE also gives you the option to (compile and) run your code, from within +the editor. + +Simple Shell Scripts +==================== + +A shell script is simply a sequence of commands, that are put into a file, +instead of entering them one by one onto the shell. The script can then be +run, to run the sequence of commands in a single shot instead of manually +running, each of the individual commands. + +For instance, let's say we wish to create a directory called ``marks`` in the +home folder and save the results of the students into a file +``results.txt``. + +We open our editor and save the following text to ``results.sh`` + +:: + + #!/bin/bash + mkdir ~/marks + cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | sort > ~/marks/results.txt + +We can now run the script, + +:: + + $ ./results.sh + +We get an error saying, Permission denied! Why? Can you think of the +reason? (Hint: ``ls -l``). Yes, the file doesn't have execute permissions. +We make the file executable and then run it. + +:: + + $ chmod u+x results.sh + $ ./results.sh + +We get back the prompt. We can check the contents of the file +``results.txt`` to see if the script has run. + +So, here, we have our first shell script. We understand almost all of it, +except for the first line of the file. The first line is used to specify +the interpreter or shell which should be used to execute the script. In +this case, we are asking it to use the bash shell. + +Once, the script has run, we got back the prompt. We had to manually check, +if the contents of the file are correct, to see if the script has run. It +would be useful to have our script print out messages. For this, we can use +the ``echo`` command. We can edit our ``results.sh`` script, as follows. + +:: + + #!/bin/bash + mkdir ~/marks + cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | sort > ~/marks/results.txt + echo "Results generated." + +Now, on running the script, we get a message on the screen informing us, +when the script has run. + +Let's now say, that we wish to let the user decide the file to which the +results should be written to. The results file, should be specifiable by an +argument in the command line. We can do so, by editing the file, as below. + +:: + + #!/bin/bash + mkdir ~/marks + cut -d " " -f 2- marks1.txt | paste -d " " students.txt - | sort > ~/marks/$1 + echo "Results generated." + + +The ``$1`` above, corresponds to the first command line argument to the +script. So, we can run the script as shown below, to save the results to +``grades.txt``. + +:: + + $ ./results.sh grades.txt + +When we run the ``results.sh`` file, we are specifying the location of the +script by using ``./``. But for any of the other commands (even if they may +not be shell scripts), we didn't have to specify their locations. Why? The +shell has a set of locations where it searches, for the command that we are +trying to run. These set of locations are saved in an "environment" +variable called PATH. We shall look at environment variables, again, later. +But, let us look at what the value of the PATH variable is. To view the +values of variables, we can use the echo command. + +:: + + $ echo $PATH + +So, these are all the paths that are searched, when looking to execute a +command. If we put the results.sh script in one of these locations, we +could simply run it, without using the ``./`` at the beginning. + +Variables +--------- + +As expected, it is possible to define our own variables inside our shell +scripts. For example, + +:: + + name="FOSSEE" + +creates a new variable ``name`` whose value is ``FOSSEE``. To refer to this +variable, inside our shell script, we would refer to it, as ``$name``. +**NOTE** that there is no space around the ``=`` sign. + +:: + + ls $name* + +It is possible to store the output of a command in a variable, by enclosing +the command in back-quotes. + +:: + + count=`wc -l wonderland.txt` + +saves the number of lines in the file ``wonderland.txt`` in the variable +count. + +Comments +-------- + +The ``#`` character is used to comment out content from a shell script. +Anything that appears after the ``#`` character in a line, is ignored by +the bash shell. + +Control structures and Operators +================================ + +We can have if-else constructs, for and while loops in bash. Let us look at +how to write them, in this section. + +To write an if, or an if-else construct, we need to check or test for a +condition. ``test`` command allows us to test for conditions. ``test`` has +a whole range of tests that can be performed. The man page of ``test`` +gives a listing of various types of tests that can be performed with it. + +Let's write a simple script with an ``if`` condition that tests whether a +directory with a particular name, is present or not. + +``if`` +------ + +Let's save the following code to the script ``dir-test.sh`` + +:: + + #!/bin/bash + if test -d $1 + then + echo "Yes, the directory" $1 "is present" + fi + +When the script is run with an argument, it prints a message, if a +directory with that name exists in the current working directory. + +``if`` - ``else`` +----------------- + +Let's write a simple script which returns back whether the argument passed +is negative or not + +:: + + #!/bin/bash + if test $1 -lt 0 + then + echo "number is negative" + else + echo "number is non-negative" + fi + +We can run the file with a set of different inputs and see if it works. + +:: + + $ ./sign.sh -11 + +Instead of using the ``test`` command, square brackets can also be used. + +:: + + #!/bin/bash + if [ $1 -lt 0 ] + then + echo "number is negative" + else + echo "number is non-negative" + fi + +Note that the spacing is important, when using the square brackets. ``[`` +should be followed by a space and ``]`` should be preceded by a space. + +Let's create something interesting using the if-else clause. Let's write a +script, that greets the user, based on the time. + +:: + + #!/bin/sh + # Script to greet the user according to time of day + hour=`date | cut -c12-13` + now=`date +"%A, %d of %B, %Y (%r)"` + if [ $hour -lt 12 ] + then + mess="Good Morning $LOGNAME, Have a nice day!" + fi + + if [ $hour -gt 12 -a $hour -le 16 ] + then + mess="Good Afternoon $LOGNAME" + fi + + if [ $hour -gt 16 -a $hour -le 18 ] + then + mess="Good Evening $LOGNAME" + fi + echo -e "$mess\nIt is $now" + +There a couple of new things, in this script. ``$LOGNAME`` is another +environment variable, which has the login name of the user. The variables +``hour`` and ``now`` are actually taking the output of the commands that +are placed in the back quotes. + +Let us now see how to run loops in bash. We shall look at the ``for`` and +the ``while`` loops. + +``for`` +------- + +Suppose we have a set of files, that have names beginning with numbers +followed by their names - ``08 - Society.mp3``. We would like to rename +these files to remove the numbering. How would we go about doing that? + +It is clear from the problem statement that we could loop over the list of +files and rename each of the files. + +Let's first look at a simple ``for`` loop, to understand how it works. + +:: + + for animal in rat cat dog man + do + echo $animal + done + +We just wrote a list of animals, each animal's name separated by a space +and printed each name on a separate line. The variable ``animal`` is a +dummy or a loop variable. It can then be used to refer to the element of +the list that is currently being dealt with. We could, obviously, use +something as lame as ``i`` in place of ``animal``. + +To generate a range of numbers and iterate over them, we do the following. + +:: + + for i in {5..10} + do + echo $i + done + +Now, we use a ``for`` loop to list the files that we are interested in. + +:: + + for i in `ls *.mp3` + do + echo "$i" + done + +If the file-names contain spaces, ``for`` assumes each space separated word +to be a single item in the list and prints it in a separate line. We could +change the script slightly to overcome this problem. + +:: + + for i in *.mp3 + do + echo "$i" + done + +Now, we have each file name printed on a separate line. The file names are +in the form ``dd - Name.mp3`` and it has to be changed to the format +``Name.mp3``. Also, if the name has spaces, we wish to replace it with +hyphens. + +:: + + for i in *.mp3 + do + echo $f|tr -s " " "-"|cut -d - -f 2- + done + +Now we just replace the echo command with a ``mv`` command. + +:: + + for i in *.mp3 + do + mv $i `echo $f|tr -s " " "-"|cut -d - -f 2-` + done + +``while`` +--------- + +The ``while`` command allows us to continuously execute a block of commands +until the command that is controlling the loop is executing successfully. + +Let's start with the lamest example of a while loop. + +:: + + while true + do + echo "True" + done + +This, as you can see, is an infinite loop that prints the ``True``. + +Say we wish to write a simple program that takes user input and prints it +back, until the input is ``quit``, which quits the program. + +:: + + while [ "$variable" != "quit" ] + do + read variable + echo "Input - $variable" + done + exit 0 + +Environment Variables +--------------------- + +Environment variables are way of passing information from the shell to the +programs that are run in it. Programs are often made to look "in the +environment" for particular variables and behave differently based on what +their values are. + +Standard UNIX variables are split into two categories, environment +variables and shell variables. In broad terms, shell variables apply only +to the current instance of the shell and are used to set short-term working +conditions; environment variables have a farther reaching significance, and +those set at login are valid for the duration of the session. By +convention, environment variables have UPPER CASE and shell variables have +lower case names. + +Here are a few examples of environment variables, + +:: + + $ echo $OSTYPE + linux-gnu + $ echo $HOME + /home/user + +To see all the variables and their values, we could use any of the +following, + +:: + + $ printenv | less + $ env + +We have looked at the PATH variable, in the previous section. We shall now +use the ``export`` command to change it's value. + +:: + + $ export PATH=$PATH:$HOME/bin + +See the difference in value of PATH variable before and after modifying it. + +``export`` command is used to export a variable to the environment of all +the processes that are started from that shell. + +Miscellaneous Tools +=================== + +Finally, here are a bunch of tools, that will prove to be handy in your day +to day work. These tools will help you quickly perform tasks like searching +for files, comparing files and checking if they are the same, viewing the +exact differences between them. + +find +---- + +The ``find`` command lets you find files in a directory hierarchy. It +offers a very complex feature set allowing you to search for files with a +wide range of restrictions. We shall only look at some of the most +frequently used ones. You should look at the man page, for more. + +To find all files, which end with an extension, ``.pdf``, in the current +folder and all it's subfolders, + +:: + + $ find . -name "*.pdf" + +To list all the directory and sub-directory names, + +:: + + $ find . -type d + +``find`` allows you to set limits on file-size, modification time and whole +lot of other things. + +``cmp`` +------- + +To compare two files, whether they are identical or not, we can use the +``cmp`` command. Let us consider some situation, we run ``find`` to locate +some file, and it turns out that we have a file with same name in different +location. + +If we are unsure, whether both the files are the same, we can use the +``cmp`` command to check if the files are identical. + +:: + + $ find . -name quick.c + ./Desktop/programs/quick.c + ./c-folder/quick.c + $ cmp Desktop/programs/quick.c c-folder/quick.c + +If the cmp command doesn't return any output, it means that both files are +exactly identical. If there are any differences in the file, it gives you +the exact byte location at which the first difference occurred. + +Here is the output, after we made a small change to one of the files. + +:: + + $ cmp Desktop/programs/quick.c c-folder/quick.c + Desktop/programs/quick.c c-folder/quick.c differ: byte 339, line 24 + + +``diff`` +-------- + +Now, we may not be happy with just the knowledge that the files are +different. We may want to see the exact differences between the files. +The ``diff`` command can be used to find the exact differences between the +files. + +:: + + $ diff Desktop/programs/quick.c c-folder/quick.c + +We get back a line by line difference between the two files. The ``>`` mark +indicates the content that has been added to the second file, and was not +present in the first file. The ``<`` mark indicates the lines that were +present in the first file, but are not existent in the second file. + +``tar`` +------- + +You would often come across (archive) files which are called *tarballs*. A +tar ball is essentially a collection of files, which may or may not be +compressed. Essentially, it eases the job of storing, backing up and +transporting multiple files, at once. + +Extracting an archive +~~~~~~~~~~~~~~~~~~~~~ + +The following command extracts the contents of the ``allfiles.tar`` tarball +to the directory extract. + +:: + + $ mkdir extract + $ cp allfiles.tar extract/ + $ cd extract + $ tar -xvf allfiles.tar + +The option, ``x`` tells ``tar`` to extract the files in the archive file +specified by the ``f`` option. The ``v`` option tells ``tar`` to give out a +verbose output. + +Creating an archive +~~~~~~~~~~~~~~~~~~~ + +Similarly, if we wish to create a ``tar`` archive, we use the ``c`` option +instead of the ``x`` option. For instance, the command below creates an +archive from all the files with the ``.txt`` extension. + +:: + + $ tar -cvf newarchive.tar *.txt + + +Compressed archives +~~~~~~~~~~~~~~~~~~~ + +You can also create and extract compressed archives using ``tar``. It +supports a wide variety of compressions like gzip, bzip2, lzma, etc. + +We need to add an additional option to ``tar`` to handle these +compressions. + + ++-------------+------------+ +| Compression | Option | ++-------------+------------+ +| gzip | ``-z`` | +| bzip2 | ``-j`` | +| lzma | ``--lzma`` | ++-------------+------------+ + + +So, if we wished to create a gzip archive in the previous command, we +change it to the following + +:: + + $ tar -cvzf newarchive.tar.gz *.txt + +Customizing your shell +---------------------- + +What would you do, if you want bash to execute a particular command each +time you start it up? For instance, say you want the current directory to +be your Desktop instead of your home folder, each time bash starts up. How +would you achieve this? Bash reads and executes commands in a whole bunch +of files called start-up files, when it starts up. + +When bash starts up as an interactive login shell, it reads the files +``/etc/profile``, ``~/.bash_profile``, ``~/.bash_login``, and +``~/.profile`` in that order. + +When it is a shell that is not a login shell, ``~/.bashrc`` is read and the +commands in it are executed. This can be prevented using the ``--norc`` +option. To force bash to use another file, instead of the ``~/.bashrc`` +file on start-up, the ``--rcfile`` option may be used. + +Now, you know what you should do, to change the current directory to you +Desktop. Just put a ``cd ~/Desktop`` into your ``~/.bashrc`` and you are +set! + +This example is quite a simple and lame one. The start-up files are used +for a lot more complex things than this. You could set (or unset) aliases +and a whole bunch of environment variables in the ``.bashrc``, like +changing environment variables etc. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 75 + End: diff --git a/lecture_notes/ult/index.rst b/lecture_notes/ult/index.rst new file mode 100644 index 0000000..beaf301 --- /dev/null +++ b/lecture_notes/ult/index.rst @@ -0,0 +1,6 @@ +================== + Using Linux Tools +================== + +.. include :: handout.rst +.. include :: exercises.rst diff --git a/lecture_notes/ult/module_plan.rst b/lecture_notes/ult/module_plan.rst new file mode 100644 index 0000000..5557222 --- /dev/null +++ b/lecture_notes/ult/module_plan.rst @@ -0,0 +1,95 @@ +Module 1: Using Linux Tools +============================ + +Module Objectives +----------------- + +After successfully completing this module a participant will be able to: + +* Understand the design philosophy of \*nix {U} +* Use Linux as their day-to-day operating system {Ap} +* Use the text processing tools such as 'grep', 'tr' {Ap} +* Write and execute (bash) shell scripts {Ap} + +.. * Use a text editor comfortably {Ap} + +Suggested Reading +----------------- + +(1) "In the beginning..." by Neal Stephenson +(2) "The Unix Programming Environment" by Kerninghan and Pike + +**Initial Session Plan** + ++---------+----------------------------------------------+----------+ +| Session | Topic | Duration | ++---------+----------------------------------------------+----------+ +| 1 | What is Linux? FOSS Philosophy | 5 min | +| | | | +| | Getting Started | 15 min | +| | - login | | +| | - pwd | | +| | - ls | | +| | - mkdir | | +| | - cd | | +| | - touch | | +| | | | +| | Getting help | 10 min | +| | - man | | +| | - command line flags | | +| | - apropos | | +| | | | +| | Basic File Handling | 10 min | +| | - cp | | +| | - mv | | +| | - rm | | +| | | | +| | Linux File Hierarchy, permissions, ownership | 10 min | +| | - hier | | +| | - ls -l | | +| | - chmod | | +| | - chown | | +| | | | ++---------+----------------------------------------------+----------+ +| 2 | Looking at files | 15 min | +| | - cat | | +| | - wc | | +| | - less | | +| | - head | | +| | - tail | | +| | - cut | | +| | - paste | | +| | | | +| | Role of Command Shell | 20 min | +| | - redirection and piping | | +| | - stdin, stdout, stderr | | +| | - tab-completion | | +| | - history | | +| | - meta characters | | +| | | | +| | Text Processing | 15 min | +| | - sort | | +| | - grep | | +| | - tr | | +| | - uniq | | +| | | | ++---------+----------------------------------------------+----------+ +| 3 | Writing Simple Shell scripts | 10 min | +| | - echo | | +| | - command line parameters | | +| | - PATH | | +| | - chmod and execute permission | | +| | | | +| | Control structures and operators | 25 min | +| | - test, [ ] | | +| | - if, if-else | | +| | - for | | +| | - while | | +| | - Environment variables | | +| | | | +| | Miscellaneous Tools | 15 min | +| | - tar | | +| | - cmp, diff | | +| | - find | | +| | - customizing your shell | | ++---------+----------------------------------------------+----------+ diff --git a/lecture_notes/vcs/exercises.rst b/lecture_notes/vcs/exercises.rst new file mode 100644 index 0000000..de55478 --- /dev/null +++ b/lecture_notes/vcs/exercises.rst @@ -0,0 +1,59 @@ +Exercises +========= + +1. ``clone`` the repository from http://fossee.in:9000 into a directory + called sees. You should see a folder ``punchagan`` with a lone directory + ``01-mercurial`` inside that. The ``log`` should show you the lone commit + of the repository. + +#. The next step is to create a folder for yourself inside the repository. + The idea is to create a central repository for the course, where every + participants files are put in his own folder (within a chapter + sub-folder). You are expected to commit future class-work to this + repository. + + Before beginning this exercise, set your username in you global ``hgrc`` + +#. Create a new sub-folder (at the same level as ``punchagan`` with your + name.) Add ``01-mercurial`` as a sub-folder to it. Copy the + ``questions.txt`` from ``punchagan/01-mercurial`` to + ``<your-name>/01-mercurial``. Now, commit your changes with a meaningful + commit message and ``push`` . If ``push`` fails, ``pull`` , ``merge``, + ``commit`` and then ``push``. + +#. Pull from the repo. Update. Use ``hg log`` to see the log history of the + repository. + +#. Answer the questions in ``questions.txt``. Commit your changes with a + meaningful commit message and push them. (If required, ``pull`` , + ``merge``, ``commit`` and then ``push``) + +#. Wait for your neighbor to finish making his/her changes. Help him/her if + required. Once both of you are ready, pull changes from the repository and + update. + + Now, add one question each, at the bottom of your own ``questions.txt`` + file and your neighbor's file. Preferably, the questions should be about + ``hg`` , but you may, let your creativity run wild. ;) Commit the changes + and push them. Resolve merge conflicts, as required. + +#. Answer the new questions that were added by your neighbor, both to his/her + file and your file. Commit changes. Push. + +#. Edit the file ``people.txt`` in ``punchagan/01-mercurial`` . Add your + name, followed by a colon, followed by a comma separated list of your + interests. Commit your changes and push. + +#. Edit the file ``story.txt`` in the folder ``punchagan/01-mercurial`` and + add one sentence at the end of the present story. Commit your changes and + push them. Wait until at least 3 other people change the file, before you + make your next change. This can continue for as long as you like. ;) + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + diff --git a/lecture_notes/vcs/handout.rst b/lecture_notes/vcs/handout.rst new file mode 100644 index 0000000..6ee0317 --- /dev/null +++ b/lecture_notes/vcs/handout.rst @@ -0,0 +1,1208 @@ +.. highlight:: console + +=============== +Version Control +=============== + +At the end of this session, you will be able to: + +- Understand what Version Control is, and the need for it +- Create and use repository on a daily basis +- Clone existing repositories, from the web +- View the history of a repository +- Make changes to a repository and commit them +- Work collaboratively with a team + +Introduction +============ + +Version control is just a way to track your files over time and share them. +This allows you to go back to older versions when something goes wrong, see +what changed when and why, collaborate on a single piece of work with a bunch +of people. + +Like this +`blog <http://karlagius.com/2009/01/09/version-control-for-the-masses/>`_ +aptly points out, "Version control is one of those weird, geeky things that +never really gained much ground in non-geek fields, despite the fact that +it’s blindingly useful." In this course, we are going to see a handful of +such things, which are widely used in the programmer world, but not so much +in the scientific computing world, even when if they would be very useful. + +Version control is just a way of backing up your files, before making changes +to it. Most people would have cooked up their own version control system, +without realizing, there are tools built by others, which make this task much +more organized and systematic. You surely would've saved your files, some +time or the other as ``oldproject.py``, ``latestproject.py`` and so on, or +date-tagging them as ``project-21-01-10.py``, ``project-20-02-10.py`` and so +on. + +It is, in some ways, similar to playing a video game. We generally play games +in stages, saving the game, each time we finish a stage or complete a task. +We continue playing, but we could, if necessary, choose to go back to one of +the saved states and start over. In this manner we could change the state of +the game. + +Why Use Version Control +======================= + +We have seen that one of the main motivation to use a version system control +system is the ability to go back to a working version of the file, when +something stops working. Below are a few more advantages of using an +automated version control system. + + - It tracks the history and evolution of a project. It allows you to + track what changes were made at what point of time, when and by whom. + + - If you are collaborating, as a team on a project, a version control + system will make it much easier for you to collaborate. It allows you + to work simultaneously on the same file, without worrying about merging + your changes. + + - A good version control system will help you efficiently track down bugs + and pin-point the changes that introduced the bug, reducing your + debugging time. + +Version control is as useful for a one man show, as it is for a big group of +people working on a project. As a student, you can use it to maintain your +course work, too. You could maintain a version controlled repository with all +your code, assignments, and other documents. Keeping your stuff version +controlled will help avoid accidental deletion of individual files etc. +Hosting it on a remote server will protect you from a local hard disk crash. + +Mercurial +========= + +Some of Version Control Tools available and used widely are: + + - ``cvs`` (Concurrent Versions System) + - ``svn`` (Subversion) + - ``hg`` (Mercurial) + - ``git`` + +Each of these tools have some unique functionality and their own merits and +de-merits. In this course, we shall learn to use Mercurial or ``hg``. +Once you know how to use ``hg``, you could easily try other tools and switch +to one that you feel most comfortable with. + +Why ``hg`` ? +------------ + + - easy to learn and use. + - lightweight. + - scales excellently. + - based on Python. + +Installation +------------ + +- For Linux based systems, hg is available in most of package management. So + for say Ubuntu systems:: + + $ sudo apt-get install mercurial + + will be all you need to install hg. Similarly Fedora users can use yum to + install hg. + +- For Windows and Mac OS X systems the setup can be downloaded from + http://mercurial.selenic.com/downloads/ and standard installation can be + followed. + +Just say ``hg`` in your shell, to see some of the commands that ``hg`` +provides and say ``hg version`` to see the version of ``hg`` that has +been installed on your system. + +In this section, we have seen + + - the motivation to use version control + - an analogy of version control with playing a video game + - how to check if mercurial is installed, and it's version using ``hg + version`` + +Let there be a Repository +========================= + +At the end of this section, you will be able to - + + - initialize a new repository, + - obtain the status of a repository, + - add new files to a repository, + - take snapshots of a repository, + - view the history of a repository, + - and set your user information for ``hg`` + +To start using Mercurial (or ``hg``) and get the benefits of using a version +control system, we should first have a **repository**. A repository is a +folder with all your files and a store of all the changes that were made to +it. To save disk space, ``hg`` doesn't save all the files, but only saves +only a series of changes made to the files. + +We have talked of an example of how we cook up our own version control +systems. Mercurial does almost the same thing with one major difference. It +doesn't keep track of individual files. It keeps snapshots of the whole +directory (or repository), instead of individual files. + +A repository can either be started using an ``init`` command or an existing +repository could be **cloned**. + +Let us look at creating our own repository, now. We can look at obtaining +already existing repositories, at a later stage. + +Let's say we have a folder called ``book``, which has all the chapters of a +book as text files. Let us convert that folder, into a ``hg`` repository. + +:: + + $ cd book/ + $ ls -a + . .. chapter1.txt chapter2.txt chapter3.txt + + +We have three chapters in the folder. We convert this folder into a mercurial +repository using the ``hg init`` command + +:: + + $ hg init + $ ls -a + . .. .hg chapter1.txt chapter2.txt chapter3.txt + + +The ``.hg`` directory indicates that our book directory is now a ``hg`` +repository. Mercurial keeps all the history of the changes made, and a few +other config files, etc. in this directory. The directory, ``book`` is called +our **working directory**. + +Adding Files +------------ + +We now have a fresh repository, but all our files are not being tracked or +watched by ``mercurial``, yet. We need to explicitly ask it to watch the +files, that we want it to. + +To see this use the ``hg status`` command. +:: + + $ hg status + ? chapter1.txt + ? chapter2.txt + ? chapter3.txt + + +We see the three files for the chapters, but they are preceded by a ``?`` +mark. What does it mean? + +We use the ``help`` command to see what this means. +:: + + $ hg help status + ... + The codes used to show the status of files are: + + M = modified + A = added + R = removed + C = clean + ! = missing (deleted by non-hg command, but still tracked) + ? = not tracked + I = ignored + = origin of the previous file listed as A (added) + ... + +By looking at the codes, it is clear that our files are not *yet* being +tracked by ``hg``. We now use the add command to ask ``hg`` to track these +files. + +The ``status`` command gives the *status* of our working-directory at this +point in time. Using this command after every ``hg`` command you use, is a +good idea, at least until you are reasonably comfortable with the use of +``hg``. + +:: + + $ hg add + adding chapter1.txt + adding chapter2.txt + adding chapter3.txt + $ hg status + A chapter1.txt + A chapter2.txt + A chapter3.txt + $ + +This simply adds all the files in the (working) directory, to the repository. +As expected, the ``status`` command shows an ``A`` before he file names. We +could also specify files individually, for example + +:: + + $ hg add chapter1.txt + adding chapter1.txt + + +**Note**: If you have deleted files, ``hg status`` will show you the status +code ``!``. You can, then, tell ``hg`` to stop tracking these files, using +the ``hg remove`` command. Look at ``hg help remove`` for more details. + +Taking Snapshots +---------------- + +We have added a set of new files to the repository, but we haven't told +mercurial to remember these changes, i.e., to take a snapshot at this point +in time. We do this by using the ``commit`` command. + +:: + + $ hg commit -u "Puneeth Chaganti <punchagan@fossee.in>" -m "Initial Commit." + +The ``-u`` parameter allows us to specify the user details. It is a general +good practice to use full name followed by the email id. The ``-m`` parameter +allows us to give the commit message --- a message describing the changes +that are being committed. + +Mercurial has now taken a snapshot of our repository and has attached our +description along with it. To see the status of the files in the repository, +use the ``hg status`` command. + +:: + + $ hg st + +The command does not return anything, when there are no uncommitted changes. +Also, notice that I have started getting lazy and used only a short name +``st`` for the status command. Mercurial accepts short names, as long as they +can be disambiguated (just like tab completion). + +Snapshot's Thumbnail views +-------------------------- + +To see the history of the changes to our repository, we use ``hg log``. We +can view the change that we just made to our repository. + +:: + + $ hg log + changeset: 0:cbf6e2a375b4 + tag: tip + user: Puneeth Chaganti <punchagan@fossee.in> + date: Fri Jan 28 14:04:07 2011 +0530 + summary: Initial Commit + + +As we already discussed, mercurial keeps track of the changes that are made +to the files in the repository. Notice, that our ``log`` is showing a +**changeset**. A change set is nothing but a set of changes made to the +repository between two consecutive commits (the action of taking snapshots). +Notice that ``hg`` also shows the date at which the commit was made and the +description of the changeset. + +User information +---------------- + +But there are two things, that can be changed. Firstly, it is unnecessary to +keep typing the user information each and every time we make a commit. +Secondly, it is not very convenient to enter a multi-line commit message from +the terminal. To solve these problems, we set our user details and editor +preferences in the ``.hgrc`` file in our home folder. (``$HOME/.hgrc`` on +Unix like systems and ``%USERPROFILE%\.hgrc`` on Windows systems) This is a +global setting for all the projects that we are working on. We could also set +the details, at a repository level. We shall look at this in due course. + +We open the file in our favorite editor and add the username details and our +editor preferences. + +:: + + $ emacs ~/.hgrc + [ui] + username = Puneeth Chaganti <punchagan@fossee.in> + editor = emacs + +We have now set the username details for mercurial to use, in all our future +commits. (Note: You can also set user preferences at the repository level. +Exercise-N asks you to do that) + +Let us now make another commit to see if this has taken effect. Let us +add author information to all the chapters that we have. + +:: + + Author: Puneeth Chaganti + + +Once we have added this to all the files, let us commit this change. We again +used the ``hg commit`` command to commit the changes that we have made. + +:: + + $ hg commit + +We are now prompted with a window of our favorite editor. We can now type out +our commit message in the editor window. + +There are some recommended practices for commit messages, too. It is a +general practice to have a summary line in the commit message which is no +longer than 60 to 65 characters giving a summary of the change committed. +This is followed up with an explanation of why this was changed, what is the +effect of this change, known bugs/issues remaining, if any, etc. + +:: + + Add author info to all the chapters + + All the chapters must have an author info. Added Puneeth Chaganti + as the author. New authors can be added in newlines. + + HG: Enter commit message. Lines beginning with 'HG:' are removed. + HG: Leave message empty to abort commit. + +``hg log`` should now show us both the changes that we have made. Notice that +the username settings are being used and also, the summary of the changeset +shows only the first line in the description that we have added. Also, notice +that ``hg`` shows the commits in the reverse chronological order, which is +useful. + +In this section, we have learn to - + + - initialize a new repository using ``hg init``, + - get the status of a repository using ``hg status``, + - make sense out of the various status codes in the output of ``hg + status``, + - use the ``hg help`` to get help about any ``hg`` command, + - make commits of changes to files, using ``hg commit`` + - view the history of the repository using the ``hg log`` command, + - and, set our user information in the global ``hgrc`` file. + +But why commit? +=============== + +At the end of this section, you will be able to - + + - undo changes to your repository, + - view the differences between any two states of a repository, + - understand how revisions are numbered and use it as arguments to + commands, + +You must already be wondering, why we need all the overhead of +``commit`` and ``log``, etc. What is all this fuss about? "Isn't it +just a waste of time?" + +Reverting Changes +----------------- + +While you were wondering, let's say your friend walks in and together you +make a lot of changes. + +1. You replace all the occurrences of ``&`` in ``chapter1.txt`` with +``and``. +2. You delete the ``chapter3.txt`` file. + +:: + + $ rm chapter3.txt + $ hg st + M chapter1.txt + ! chapter3.txt + + +But after a while, you realize that these changes are unwarranted. You +want to go back to the previous state, undoing all the changes that +you made, after your friend arrived. + +The undo in your editor may allow undoing the first change (if you +haven't closed it after making the changes) but there's no way you +could get back your ``chapter3.txt`` file, using your editor. But +don't worry. Mercurial to the rescue! + +We shall use the ``revert`` command of ``hg`` to undo all the changes +after the last commit. As we want to undo all the changes, we use the +``revert`` command with the ``--all`` argument. + +:: + + $ hg revert --all + reverting chapter1.txt + reverting chapter3.txt + $ hg st + ? chapter1.txt.orig + $ ls + chapter1.txt chapter1.txt.orig chapter2.txt chapter3.txt + +As you can see the ``chapter3.txt`` file has been restored. But ``hg`` +gives you a new file ``chapter1.txt.orig``. Mercurial actually doesn't +like to delete any of the changes that you have made. So, it makes a +back-up of the file ``chapter1.txt`` in the present state and gives +you back the old file. + +If we now decide, that we want to ``redo`` the changes that we had +done to the ``chapter1``, we can just overwrite the ``chapter1.txt`` +file with the backed up file. +:: + + $ mv chapter1.txt.orig chapter1.txt + $ hg st + M chapter1.txt + +Viewing Changes +--------------- + +Let's say we now want to ``commit`` these changes, but we are not sure +of all the changes that we have made to the file, since it's been a +while after we made the changes. We could use the ``diff`` command to +see all the changes that have been made in the file. + +:: + + $ hg diff + diff -r 3163b8db10bb chapter1.txt + --- a/chapter1.txt Fri Jan 28 16:21:29 2011 +0530 + +++ b/chapter1.txt Fri Jan 28 16:22:41 2011 +0530 + @@ -8,9 +8,9 @@ + 1 Session + Table of Contents + ================= + -1 Introduction & Motivation + -2 Creating & Getting repositories + +1 Introduction and Motivation + +2 Creating and Getting repositories + 3 Revision history + -4 Making & sharing changes + -5 Merges & Conflicts + +4 Making and sharing changes + +5 Merges and Conflicts + +You see some cryptic output, but it's essentially giving you the list +of changes made to the file. All the lines that were deleted are +preceded by a ``-`` and all the new-lines are preceded by a ``+``. You +can see that the ``&`` occurrences have been replaces with ``and``. + +We should note here that, the ``diff`` wouldn't make much sense, if we had +some binary files like ``.jpg`` or ``.pdf`` files. We would see some +gibberish in the output. + +Let us now commit this change. +:: + + $ hg commit + + Replace all occurrences of & with and + + On the suggestion of Madhusudan C S. + + HG: Enter commit message. Lines beginning with 'HG:' are removed. + HG: Leave message empty to abort commit. + +:: + + $ hg log + +We can see the history of all the commits that we have made in our +project. This gives us a brief description of all the changes made, by +showing us the summary line of all the commits. What if we want to get more +details? + +We can pass an additional argument, ``-v`` or ``--verbose``, to ``hg log`` +to get the whole commit message, instead of just the summary. + +:: + + $ hg log -v + +As you can see, the logs have started getting longer (and hence have been +dropped from the output) and getting out of our screen. Also, we are not +always, interested to see the whole history of the project. It would often +suffice to see the last few commits. + +To limit the output of ``hg log``, we could use the ``-l`` or ``--limit`` +argument +:: + + $ hg log -v -l3 + +This will give us log of only the last three commits and not the whole +history of the project. + +Revision Numbering +------------------ + +Often, the level of detail provided by the commit messages is also not +enough. We would want to see what *exactly* changed with a commit, probably +as a ``diff``. We could do that using **revision numbers**. + +Have a look at the logs that the previous ``log`` command has +printed and look at the ``changeset`` line. It shows a number followed +by a semi-colon and some long hexa-decimal string. The number is +called the **revision number**. It is an identifier for the commit, +and can be along with various commands to specify the revision number, +if required. + +Let's say we wish to see the changes between revision 1 and revision 2. We +shall use the ``diff`` command to do this. +:: + + $ hg diff -r1 -r2 + +The diff command takes two revision numbers as arguments and gives the +changes made from revision in the first argument to revision in the second +argument. +:: + + $ hg diff -r0 -r2 + +The above command will show all the changes made after revision 0 up to +revision 2. + +The revision number can also be passed as an argument to many other commands. +For instance, we can check the logs of the very first commit, by saying +:: + + $ hg log -r0 + changeset: 0:cbf6e2a375b4 + tag: tip + user: punchagan@shrike.aero.iitb.ac.in + date: Fri Jan 28 14:04:07 2011 +0530 + summary: Initial Commit + +You could also specify a range of commits whose logs you would like to +see. Say, we would like to see the last two commits, +:: + + $ hg log -r0:2 + +You could also see the changes made to a particular file, in the +specified range of the commits. Say, we wish to see the changes made +to the ``chapter2.txt`` file in the last two commits. +:: + + $ hg log -r0:2 chapter2.txt + changeset: 1:3163b8db10bb + user: Puneeth Chaganti <punchagan@fossee.in> + date: Fri Jan 28 16:21:29 2011 +0530 + summary: Add author info to all the chapters + +Notice that it shows only the logs of revision 1, since no changes +were made to the specified file in the second commit. + +In this section, we have learnt to - + + - undo changes to the repository using ``hg revert``, + - view changes done to the repository using ``hg diff`` + - use revision numbers as arguments to different ``hg`` commands + +Collaborating with Mercurial +============================ + +At the end of this section, you will be able to - + + - clone existing repositories, + - share your repositories with peers, + - use version control for collaborating with your peers, + +When motivating the use of version control systems, we spoke a lot about +collaboration and sharing our changes with our peers. Let us now see how we +can share our project with our peers and collaborate with them. + +Cloning Repositories +-------------------- + +For this purpose let us create a central repository, a copy of our +repository, which is different from the one in which we are working. The +``clone`` command is used to **clone** or replicate an existing repository. + +:: + + $ hg clone book book-repo + +This creates a copy of our repository, ``book``, with the name ``book-repo``. +The syntax of the ``clone`` command is -- ``hg clone SOURCE [DEST]``, where +the optional argument DEST is being represented in brackets. Here we are +giving book-repo as the destination. + +The clone command can be used to replicate already existing repositories, +either on your own machine or on some remote machine somewhere on the +network. Since, ``hg`` maintains a copy of the full repository with every +copy of the repository, the two copies that we have are exactly equivalent. + +``book-repo`` is the repository we shall be using as a central repository +and share it with our peers. + +Sharing Repositories +-------------------- + +A mercurial repository can be shared in multiple ways. We shall use the +``http`` protocol to share the repository. Mercurial comes inbuilt with a +tiny server that can be used to share your repository over the network. To +start sharing the repository, we say + +:: + + $ cd ../book-repo + $ hg serve + +This will start serving the repository on the network on the port 8000. +Anybody in your network can access the repository in their browsers. Let us +see how it looks, in our own browser. We open the url `http://localhost:8000` +in our browser. + +Let's say, our friend Madhu, now wants to clone this repository. He will use +our ip-address and the port on which we are serving the repository, to clone +the repository. Instead of using two machines, for the purposes of +demonstration, we shall clone into our own machine, with a different name. + +:: + + $ hg clone http://192.168.1.101:8000 book-madhu + +This will clone the repository to the folder, ``book-madhu``. The log of the +repository will, obviously, be the same as our original repository. + +:: + + $ hg log + +Sharing Changes +--------------- + +Let's say, Madhu now makes some changes to the repository. + +1. He adds his name to the Authors list. +2. He moves down the Getting repositories part into a different section. + +:: + + $ hg diff + diff -r 98f7f4a1bb4d chapter1.txt + --- a/chapter1.txt Fri Jan 28 16:24:42 2011 +0530 + +++ b/chapter1.txt Fri Jan 28 23:03:37 2011 +0530 + @@ -2,6 +2,7 @@ + ======================= + + Author: Puneeth Chaganti + + Madhusudan CS + Date: 2011-01-28 13:58:47 IST + + + @@ -9,8 +10,9 @@ + Table of Contents + ================= + 1 Introduction and Motivation + -2 Creating and Getting repositories + +2 Creating + 3 Revision history + 4 Making and sharing changes + -5 Merges and Conflicts + +5 Getting repositories + +6 Merges and Conflicts + +He then commits these changes and **pushes** them to the central repository +that we have created. + +:: + + $ hg commit + $ hg push + pushing to http://192.168.1.101:8000 + searching for changes + ssl required + +The push failed, obviously, since we have not taken care of access rights +etc. It doesn't make much sense to allow anybody to make changes to a public +repository, by default. We will need to make changes to the settings of the +repository to allow this. **Note**: This is obviously not a safe way to share +your repository, but for our purposes, this is sufficient. + +We add the following lines to the ``.hg/hgrc`` of the ``book-repo`` +repository. +:: + + [web] + push_ssl=False + allow_push=* + +This will allow anybody to push to the repository, now. + +By the way, this ``hgrc`` is a repository level configuration file. We could +also set the details of the user information in this file. + +Madhusudan can now push and his changes will appear in the central +repository. + +:: + + $ hg push + +Let's confirm it in the web interface that we started with the ``hg serve`` +command. + +Pulling Changes +--------------- + +Let us now **pull** these changes into our original repository ``book`` that +we have been working with. Before pulling the changes, we can use the command +``hg incoming`` to see the changes that have been made to the repository +after our last **pull** and the changesets that will be coming into our +repository after we do a **pull**. + +:: + + $ hg incoming + abort: repository default not found! + +What is going on here? This is because, we didn't clone our repository +``book`` from the central repository ``book-repo``. We can now add the +location of the central repository to the ``hgrc`` file, of this project. + +:: + + [paths] + default = /home/punchagan/book-repo + +Now, we can check the incoming changes. + +:: + + $ hg incoming + searching for changes + changeset: 3:3cd54926dbea + tag: tip + user: Madhusudan CS <madhusudancs@fossee.in> + date: Fri Jan 28 23:08:25 2011 +0530 + summary: Add myself as author; Move getting repositories to section 5 + + +To now **pull** these changes, we use the ``pull`` command. + +:: + + $ hg pull + pulling from /home/punchagan/book-repo + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + + +*Note* that ``hg`` is giving us a message, asking us to run a ``hg update`` + to get a working copy. Let us try to understand what this is. + +As already explained, ``.hg`` folder has all the information about the +changesets of the repository. When we do a ``pull`` the changesets from the +remote repository are pulled to our repository, but our working directory is +not affected by these changes. To see this, we could use the ``hg parent`` +command. + +:: + + $ hg parent + changeset: 2:98f7f4a1bb4d + user: Puneeth Chaganti <punchagan@fossee.in> + date: Fri Jan 28 16:24:42 2011 +0530 + summary: Replace all occurrences of & with and + +As we can see, the parent is still our last commit, and the changes made by +Madhusudan are still not in our working directory. To get these changes we do +the update as suggested by ``hg``. + +:: + + $ hg up + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg parent + changeset: 3:3cd54926dbea + tag: tip + user: Madhusudan CS <madhusudancs@fossee.in> + date: Fri Jan 28 23:08:25 2011 +0530 + summary: Add myself as author; Move getting repositories to section 5 + +As expected the **update** command updates the parent to the latest changes +that we just pulled from the remote repository. + +The update command can also be used to go back into an older revision, by +specifying the revision to which we want to go to. + +:: + + $ hg up -r1 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg parent + changeset: 1:3163b8db10bb + user: Puneeth Chaganti <punchagan@fossee.in> + date: Fri Jan 28 16:21:29 2011 +0530 + summary: Add author info to all the chapters + $ hg cat chapter1.txt + # Displays the contents of the chapter1.txt file as in revision 1. + +To return to the latest revision we just use the ``up`` or ``update`` command +without specifying any revision number. + +:: + + $ hg up + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg parent + changeset: 3:3cd54926dbea + tag: tip + user: Madhusudan CS <madhusudancs@fossee.in> + date: Fri Jan 28 23:08:25 2011 +0530 + summary: Add myself as author; Move getting repositories to section 5 + +Simultaneous Changes +-------------------- + +Ok, we have been talking about collaboration, but this is a nice situation, +where I was not changing anything while Madhusudan was changing the file, +incidentally. + +Now, let's say, both of us are editing the file at the same time, but +different parts of it. Say, I change the title of the section 2. +:: + + $ hg diff + diff -r 3cd54926dbea chapter1.txt + --- a/chapter1.txt Fri Jan 28 23:08:25 2011 +0530 + +++ b/chapter1.txt Fri Jan 28 23:45:19 2011 +0530 + @@ -10,7 +10,7 @@ + Table of Contents + ================= + 1 Introduction and Motivation + -2 Creating + +2 Creating repositories + 3 Revision history + 4 Making and sharing changes + 5 Getting repositories + $ hg commit + $ hg push + pushing to /home/punchagan/book-repo + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + +Also, let us assume Madhusudan adds an additional section called References. +:: + + $ hg diff + diff -r 3cd54926dbea chapter1.txt + --- a/chapter1.txt Fri Jan 28 23:08:25 2011 +0530 + +++ b/chapter1.txt Fri Jan 28 23:47:05 2011 +0530 + @@ -15,4 +15,4 @@ + 4 Making and sharing changes + 5 Getting repositories + 6 Merges and Conflicts + - + +7 References + $ hg commit + $ hg log + +Let us now compare the logs of the two repositories. You can see that both +the repositories have their topmost revision numbered as 4, but they are both +different. The identification number given to each revision is a local +identification. The hexadecimal string following that number is the actual +unique identification of that changeset, which will be unique across +repositories. + +What happens now, when Madhusudan tries to push his changes to the central +repository? + +:: + + $ hg push + pushing to http://192.168.1.101:8000 + searching for changes + abort: push creates new remote heads! + (did you forget to merge? use push -f to force) + + +The push failed! This is because, both of us have made changes, and they need +to be merged somehow. **Don't**, just for this one instance, take the advice +given by ``mercurial``. Using the ``-f`` would be disastrous. We will leave +out a discussion of that, for this course. + +Madhusudan now needs to pull the new changes that have been pushed to the +repository after his last pull and **merge** them with his changes. + +:: + + $ hg pull + pulling from http://192.168.1.101:8000 + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg merge + merging chapter1.txt + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, dont forget to commit) + + +We have now pull the changes from the central repository and merged them with +the changes in our repository. But, ``hg`` is warning us not to forget to +commit. Let's see what is the status of the repository at this point in time. + +:: + + $ hg st + M chapter1.txt + $ hg diff + diff -r bd57162c31f6 chapter1.txt + --- a/chapter1.txt Fri Jan 28 23:51:52 2011 +0530 + +++ b/chapter1.txt Sat Jan 29 00:00:39 2011 +0530 + @@ -10,7 +10,7 @@ + Table of Contents + ================= + 1 Introduction and Motivation + -2 Creating + +2 Creating repositories + 3 Revision history + 4 Making and sharing changes + 5 Getting repositories + +As you can see, the changes pushed by us, changing the name of the section 2, +have now been made in the repository of Madhusudan. We will now need to +commit these changes. + +:: + + $ hg commit + +We shall be using a commit message that makes it clear that we are merging. +We can now push this changes to the central repository. We could also check +the changes that will be pushed, before pushing them, using the ``hg +outgoing`` command. +:: + + $ hg outgoing + tag: tip + parent: 5:bd57162c31f6 + parent: 4:5c88c36f60de + user: Madhusudan CS <madhusudancs@fossee.in> + date: Sat Jan 29 00:02:53 2011 +0530 + summary: Merge heads. + + changeset: 5:bd57162c31f6 + parent: 3:3cd54926dbea + user: Madhusudan CS <madhusudancs@fossee.in> + date: Fri Jan 28 23:51:52 2011 +0530 + summary: Add additional References section + $ hg push + pushing to http://192.168.1.101:8000 + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 2 changes to 1 files + +The changes have now been successfully pushed! Let us look at the web +interface of the repo, to see that the changes have actually taken place. Let +us also have a look at the graph to, try and understand what has happened. + +As we can see, a branch was created, when both of us started editing the file +simultaneously, and was then merged by Madhusudan CS. + +Simultaneous Conflicting Changes +-------------------------------- + +We were lucky this time, in that we were editing separate parts of the file. +What will happen if we edited the same portion of the file, at the same time? +How would merges work? This will be the last thing that we are going to see +in this part of the course. + +Let's say both of us edit the title of the section 6. + +Let's say, I make the following changes, commit them and push them. + +:: + + $ hg diff + diff -r ce3469a9446f chapter1.txt + --- a/chapter1.txt Sat Jan 29 00:02:53 2011 +0530 + +++ b/chapter1.txt Sat Jan 29 10:30:21 2011 +0530 + @@ -14,5 +14,5 @@ + 3 Revision history + 4 Making and sharing changes + 5 Getting repositories + -6 Merges and Conflicts + +6 Merging and resolving conflicts + 7 References + $ hg commit + $ hg push + ... + added 1 changesets with 1 changes to 1 files + +Meanwhile, let's say Madhusudan was changing the same section title, as +follows. + +:: + + $ hg diff + diff -r ce3469a9446f chapter1.txt + --- a/chapter1.txt Sat Jan 29 00:02:53 2011 +0530 + +++ b/chapter1.txt Sat Jan 29 10:35:29 2011 +0530 + @@ -14,5 +14,5 @@ + 3 Revision history + 4 Making and sharing changes + 5 Getting repositories + -6 Merges and Conflicts + +6 Simple Merges and Merges with Conflicts + 7 References + $ hg commit + $ hg push + pushing to http://192.168.1.101:8000 + searching for changes + abort: push creates new remote heads! + (did you forget to merge? use push -f to force) + $ hg pull + ... + added 1 changesets with 1 changes to 1 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg merge + 0 files updated, 1 files merged, 0 files removed, 0 files unresolved + (branch merge, dont forget to commit) + + +What happens now actually depends on how Mercurial is configured and the +programs available in your machine. You will either get a diff view with 3 +panes or ``merge`` will insert markers in your file at the points where the +conflicts occur. + +If you get a 3 pane view, the first pane is the actual file, where you make +changes, to resolve the conflicts. The second pane shows the changes that you +made, to the file. The last pane shows the changes that you pulled from the +original repo. Once you are satisfied with the changes, save and quit. + +If you have a very minimal system, you might end up getting a file with +change markers, the original file being backed up. Open the file and resolve +the conflicts, deleting the markers. Once you are done, you need to tell +mercurial that you have resolved the conflicts manually. + +:: + + $ hg resolve -m chapter1.txt + +Whatever be the process you have used for the merge, you will now need to +commit your changes, just like the simple merge that we performed. + +:: + + $ hg commit -m "Merge heads." + $ hg push + +We could look at the graph of the changes, in our web interface, being served +by the ``hg serve`` command. From the graph it is clear, how the merging has +occurred. + +That brings us to the end of this tutorial on Mercurial. What we have covered +is nothing close to all the features of Mercurial. We've only scratched the +surface, but let's hope that this will get you started and you will be able +to organize your work and projects, better. + +In this section, we have learnt how to - + +- clone repositories, using ``hg clone``, +- serve our repositories via ``http`` using ``hg serve``, +- push changes to a repository using ``hg push``, +- check the changesets in a repository after last pull, using ``hg + incoming``, +- pull changes from a repository using ``hg pull`` , +- update the working directory, using ``hg update``, +- merge two heads, using ``hg merge``, +- and resolve conflicts using ``hg resolve``. + +Additional Reading +================== + +It is strongly recommended that you to go through the following topics, once +you are comfortable with using Mercurial on a day-to-day basis. + +1. ``.hgignore`` +#. ``hg rollback`` +#. ``hg bisect`` +#. ``hg backout`` + + +References +========== + + - `A Visual Guide to Version Control <http://betterexplained.com/articles/a-visual-guide-to-version-control/>`_ + - `Version Control for the Masses <http://karlagius.com/2009/01/09/version-control-for-the-masses/>`_ + - `(Illustrated) Intro to Distributed Version Control <http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/>`_ + - `Understanding Mercurial <http://mercurial.selenic.com/wiki/UnderstandingMercurial>`_ + - `A Tutorial on Using Mercurial <http://mercurial.selenic.com/wiki/Tutorial>`_ + - `Hg Init: a Mercurial tutorial <http://hginit.com/>`_ + - `Beginners Guides <http://mercurial.selenic.com/wiki/BeginnersGuides>`_ + - `Software Carpentry <http://software-carpentry.org/4_0/vc/>`_ + + +Appendix A - Definitions +======================== + +Definitions of a few commonly used terms. + +Add + Begin tracking a file (or a set of files) with Version Control. + +Branch + A diverged line of development. + +Changeset + An atomic collection of changes to the files in a repository. + +Clone + Creating a copy of an existing repository; New repo is self-contained. + +Commit + Taking a snapshot of the changes made in the repository (after the + previous snapshot) + +Conflict + Occurs when two changesets have overlapping sections that have been + modified. + +Head + A changeset with no child changesets. + +History + Cumulative of all the changesets of a repository. + +Merge + Combining two separate changesets into one merge changeset. + +Repository (repo) + - Loosely speaking, the folder with all the files and a store + of the change history. + - Strictly speaking, only the ``.hg`` directory that contains the change + history. + +Revert + Going back to previous committed state of working directory or a file. + +Revision + A particular changeset. + +Server + A machine which serves the repository. + +Tip + Most recently changed head in a repository. + +Update + Updating the working directory to a particular revision or to the tip + revision. + +Working Directory + The directory where all of the files and directories of the project are + present. + +.. + Local Variables: + mode: rst + indent-tabs-mode: nil + sentence-end-double-space: nil + fill-column: 77 + End: + diff --git a/lecture_notes/vcs/images/folder.png b/lecture_notes/vcs/images/folder.png Binary files differnew file mode 100644 index 0000000..42d01a2 --- /dev/null +++ b/lecture_notes/vcs/images/folder.png diff --git a/lecture_notes/vcs/images/mercurial_logo.png b/lecture_notes/vcs/images/mercurial_logo.png Binary files differnew file mode 100644 index 0000000..4cd736e --- /dev/null +++ b/lecture_notes/vcs/images/mercurial_logo.png diff --git a/lecture_notes/vcs/module_plan.rst b/lecture_notes/vcs/module_plan.rst new file mode 100644 index 0000000..6ad7b47 --- /dev/null +++ b/lecture_notes/vcs/module_plan.rst @@ -0,0 +1,47 @@ +Version Control +=============== + +Module Objectives +----------------- + +After successfully completing this module a participant will be able to: + + - Understand use of Version Control tools U + - Create and use repository for daily use of assignments/projects Ap + - Browse exsiting repo, make changes and commit back Ap + - Work collaboratively with a team on live project Ap + +Suggested Reading: +------------------ + +"http://mercurial.selenic.com/wiki/Tutorial" + +**Initial Session Plan** + ++---------+-----------------------+----------+ +| Session | Topic | Duration | ++---------+-----------------------+----------+ +| 1 | Introduction | 20 min | +| | - why version control | | +| | - analogy | | +| | - why hg? | | +| | | | +| | Let there be a repo | 30 min | +| | - initializing | | +| | - status | | +| | - adding files | | +| | - taking snapshots | | +| | - log | | +| | - setting userinfo | | ++---------+-----------------------+----------+ +| 2 | But Why commit? | 15 min | +| | - reverting changes | | +| | - viewing changes | | +| | - revision numbering | | +| | | | +| | Collaborating | 30 min | +| | - cloning | | +| | - serving | | +| | - pushing and pulling | | +| | - merging & conflicts | | ++---------+-----------------------+----------+ |