Python cho vi điều khiển. Chúng tôi học cách lập trình máy tính bảng đơn bằng ngôn ngữ cấp cao. Tương tác với bảng. Chuẩn bị cho công việc

| -- [ Trang 1 ] --

Chaplygin A. N.

Học lập trình với Python (Bắt đầu với Python) Bản sửa đổi: 170 Bản sửa đổi: 170 Nội dung Nội dung Nội dung............ ...... ................................................................. ................................................................. .......2 Lời nói đầu................................................. ................................................................. .................................................... ............ 5 Cảm ơn............................. ................................................................. ................................................................. ............7 Giới thiệu................................................................. ................................................................. ................................................................. ............8 z0.1. Kiến thức cơ bản................................................ ................................................................. ......................9 z0.2. Tôi có thể lấy trình thông dịch Python ở đâu?................................................. ......................................9 z0.3. Cài đặt trình thông dịch Python trên UNIX.................................................. ............ s0.3.1. Cài đặt/cập nhật Python từ gói vòng/phút.................................................. .......... s0.3.2. Cài đặt Python từ mã nguồn................................................................. .............................s0.4. Cài đặt Python trên Windows................................................................................. ......................................s0.5. Chạy chương trình viết bằng Python................................................................. ...........................s0.6. Môi trương phat triển................................................ ................................................................. ...................... Chương 1. Các khái niệm cơ bản.................................. ........................................................... .................................................h1.1. Thuật toán và chương trình................................................................................. .................................................... ............ .. h1.2. Ngôn ngữ lập trình và mức độ trừu tượng................................................................. .................................h1.3. Ngôn ngữ hình thức và ngôn ngữ tự nhiên................................................................. ................................................................. .....h1.4. Trình thông dịch và trình biên dịch.................................................................. ................................................................. ........ h1.5. Chương trình đầu tiên................................................................................. .................................................... ............h1.6. Gỡ lỗi là gì?................................................................. ................................................................. ...................... s1.6.1. Lỗi cú pháp................................................ ....................................h1.6.2. Lỗi thời gian chạy.................................................................. .................................................... .s1.6.3. Lỗi ngữ nghĩa................................................................................. ....................................h1.6.4. Quá trình gỡ lỗi................................................................................. .................................................... ......... Chương 2. Biến, phép toán và biểu thức........... ............................................h2.1 . Giá trị và kiểu................................................................................. ........................................................... .................................h2.2. Chuyển đổi kiểu................................................................................. ................................................................. .............h2.3. Biến................................................. ........................................................... ............................h2.4. Tên biến và từ khóa.................................................................. ................................................................. .. s2.5. Biểu thức................................................. ........................................................... ............................h2.6. Thực thi biểu thức.................................................................. .................................................... ........ з2.7. Các toán tử và toán hạng.................................................................. .................................................... ...................... z2.8. Thứ tự thực hiện.................................................................................. .................................................... ............h2.9. Các thao tác đơn giản nhất trên chuỗi.................................................................. ...........................s2.10. Thành phần................................................. ................................................................. ......................Chương 3. Chức năng........... ................................................................. ................................................................. ................. 3.1 . Các chương trình con.................................................................. ........................................................... .............................h3.2. Lời gọi hàm................................................................................. .................................................... .......... h3.3. Hệ thống tài liệu tham khảo................................................ ............ ...................................h3.4 . Nhập mô-đun và hàm toán học.................................................. .......... s3.5. Thành phần................................................. ................................................................. ......................h3.6. Tạo hàm................................................................................. ................................................................. .......h3.7. Các tham số và đối số.................................................................. .................................................... ............ s3.8. Các biến cục bộ................................................................................. ............................................ .......s3.9. Luồng thực thi................................................................................. .................................................... ............h3.10. Sơ đồ ngăn xếp................................................................................. ........................................................... ............ s3.11. Hàm trả về kết quả.................................................................. ................................................................. ......Chương 4. Đồ họa máy tính........................................... ................................................................. ...... Bản sửa: 170 Mục lục Chương 5. Biểu thức logic, điều kiện và đệ quy....................... .................................... h5.1. Chú thích trong chương trình.................................................................. .................................................... .....s5.2. Biểu thức Boolean đơn giản và kiểu dữ liệu Boolean................................................. ............h5.3. Các toán tử logic.................................................................................. .................................................... .......... h5.4. Thực hiện theo điều kiện và tính trống rỗng.................................................. ...........................s5.5. Nhập dữ liệu từ bàn phím.................................................................. ........................................................... ............h5.6. Các nhánh chương trình thay thế (Điều kiện theo chuỗi)................................................ ........ з5.7. Khối trống................................................................................. .................................................... .............s5.8. Lồng nhau câu điều kiện(Điều kiện lồng nhau)................................................................ .......s5.9. Đệ quy................................................................................. ............................................ ...................................s5.10. Sơ đồ ngăn xếp của các lệnh gọi đệ quy................................................................. ......................................h5.11. Độ sâu đệ quy tối đa................................................................. .................................................... ......h5.12. Số Fibonacci................................................................................. .................................................... ............ Chương 6. Chu trình........... ........................................................... ................................................................. ............ h6.1. Nhà điều hành trong khi lặp lại ................................................................. ...................................................... ............ h6.2. Bộ đếm................................................................................. ........................................................... ............................h6.3. Vòng lặp vô tận.................................................................. .................................................... ............h6.4. Nhánh thay thế của vòng lặp while................................................................. ............................s6.5. Bảng chức năng.................................................................................. .................................................... ...........h6.6. Ký tự đặc biệt và ký tự thoát.................................................................. ................................................................. ... s6.7. Dãy số Fibonacci và toán tử vòng lặp while.................................................. ............................s6.8. Câu lệnh vòng lặp lồng nhau và bảng hai chiều.................................................. ............ z6.9. Phân loại các toán tử vòng lặp.................................................................. .................................................... ...... s6.10. Cấu trúc điều khiển................................................ ........................................................... ..........Chương 7. Đường nét.................................. ................................................................. .................................................h7. 1. Toán tử lập chỉ mục.................................................................. .................................... з7 . 2. Độ dài chuỗi và chỉ số âm.................................................................. ...................................................h7. 3. Đếm và vòng lặp for.................................................................. ...................................................... ........... s7.4. Đường cắt................................................................................. ............................................ ...................... s7.5. So sánh chuỗi................................................................................. .................................................... ............ s7.6. Không thể thay đổi dòng.................................................................. ...................................................... .......... з7.7. tìm hàm................................................................................. .................................................... .............s7.8. Vòng lặp và bộ đếm................................................................................. .................................................... ...................... s7.9. Mô-đun chuỗi................................................................................. ........ ................................................................. ...................... s7.10. Phân loại ký hiệu.................................................................................. .................................................... ..... s7.11. Chuỗi Unicode................................................................................. .................................................... ............ Chương 8. Danh sách........... ................................................................. .................................................... ....h8.1. Tạo danh sách................................................................................. ............................................ ............ h8.2. Truy cập các mục trong danh sách.................................................................. ................................................................. .......h8.3. Độ dài danh sách................................................................................. .................................................... .......... s8.4. Thuộc danh mục................................................................................. ...................................................... .......... z8.5. Danh sách và vòng lặp for.................................................................. ...................................................... ........... s8.6. Các thao tác trên danh sách.................................................................. .................................................... ...................... з8.7. Liệt kê các lát cắt................................................................................. ............................................ ................... s8.8. Thay đổi danh sách................................................................................. ............................................ ............ z8.9. Xóa các mục trong danh sách.................................................................. .................................................... .......s8.10. Đối tượng và giá trị................................................................................. ........................................................... ............ z8.11. Liên kết tới các đối tượng................................................................................. ........................................................... ............ z8.12. Sao chép danh sách................................................................................. .................................................... ......... Chỉnh sửa: 170 Nội dung h8.13. Danh sách tham số................................................................................. ............................................. ................... z8.14. Danh sách lồng nhau................................................................................. ............................................ .......... z8.15. Ma trận................................................................................. ........................................................... ............ ......................s8.16. Danh sách và chuỗi................................................................................. .................................................... ................................... Chương 9. Bộ dữ liệu..... ................................................................. ................................................................. ...................... Chương 10. Từ điển........... ................................................................. ................................................. .. ....h10.1. Tạo từ điển................................................................................. .................................................... ............ h10.2. Các thao tác trên từ điển.................................................................. .................................................... ............h10.3. Phương pháp từ điển.................................................................. ........................................................... ............h10.4. Sử dụng bí danh và sao chép.................................................................. ......................................s10.5. Ma trận thưa thớt................................................................................. .................................................... ............h10.6. Gợi ý................................................................. ........................................................... ............................h10.7. Nhập số nguyên dài.................................................................. ................................................................. ...... з10.8 . Đếm chữ cái.................................................................................. .................................................... ........... Chương 11. Tệp và xử lý ngoại lệ............. ................................................................. ...................... Chương 12. Lớp và đối tượng........... ................................................................. ................................................................. ... Chương 13. Lớp và hàm................................................................. ................................................. ............Chương 14. Phương pháp........... .. ................................................................. .................................................... .......... Chương 15. Bộ đối tượng................................................. .................................................... .................... Chương 16. Kế thừa...... ................................................................. ................................................................. ..........Chương 17. Danh sách liên kết.................................. ................................................................. ......................Chương 18. Ngăn xếp........... ................................................................. . ................................................................. ......................Chương 19. Hàng đợi và hàng đợi ưu tiên........... .......................................................... ...........Chương 20 . Cây cối........... ............................................. ....................................Chương 21. Lập trình hàm... ................................................................. ............................ Phần kết luận. Mắt chim................................................................. ................................. Phụ lục A. Lời khuyên cho việc gỡ lỗi chương trình............ . ................................................................. ...................... Phụ lục B. Tạo và sử dụng module........... ............ .... Phụ lục C. Tạo kiểu dữ liệu.. .......................................................... .................... Phụ lục D. Viết chương trình GUI........ ...................... Phụ lục E. Phương pháp phát triển nhóm............ ................................................................. .. Phụ lục F. Hướng dẫn dành cho giáo viên.................................................. ........ Bản sửa đổi: 170 Lời nói đầu Lời nói đầu Mọi chuyện bắt đầu khi vào mùa hè năm 2002 tôi hoàn toàn thất vọng V ngôn ngữ php, trên đó tôi đã viết khá nhiều vào thời điểm đó. Mình chuyên về lập trình web nên việc lựa chọn tool nói chung là hợp lý nhưng khi phát triển thì dự án chính php đã cho thấy mặt tốt nhất của nó: việc thiếu các công cụ xử lý ngoại lệ xếp tầng, nhiều kế thừa và không gian tên đã ảnh hưởng đến nó.

Tóm lại, php không phù hợp với tôi cả vì lý do thực tế lẫn quan điểm tư tưởng. Như người ta nói, không có gì hạn chế khả năng suy nghĩ của lập trình viên hơn trình biên dịch/thông dịch viên.

Tôi bắt đầu tìm kiếm một giải pháp thay thế cho php. Trước php, tôi phải làm việc với ngôn ngữ Perl, ngôn ngữ này không phù hợp với tôi vì những lý do tương tự. C++ cũng không phải là ngôn ngữ thuận tiện nhất để phát triển ứng dụng web, bởi vì... Chi phí để sở hữu những ứng dụng như vậy khá cao. Và thế là tôi tình cờ gặp Python (Python, ý tưởng sử dụng Python đã được chọn bởi Dmitry Brechalov, bạn tôi, người mà chúng tôi đã trao đổi thư từ rất hiệu quả và trao đổi sách. Anh ấy nhanh chóng thành thạo Python và viết được bằng nó ngay cả đối với Psion của mình Anh ấy cũng gửi cho tôi email liên kết đến trang web của dự án Cách suy nghĩ như một nhà khoa học máy tính Học với Python (Tôi đọc cuốn sách một lần, tôi bị ấn tượng bởi cách trình bày tài liệu. Ví dụ, khái niệm về đệ quy trong cuốn sách này được giới thiệu trước các cấu trúc cú pháp thực hiện các vòng lặp và nó rất rõ ràng và dễ hiểu. thuật toán đệ quy thường được xếp vào danh mục các bài toán Olympic.

Động lực cuối cùng là khi tôi bắt đầu giảng dạy các môn tin học tại Câu lạc bộ Trí tuệ cho trẻ em từ 9 đến 13 tuổi. Các thử nghiệm với Pascal không đạt yêu cầu vì... Tôi đã phải bị phân tâm bởi sự phức tạp của việc triển khai kiểu và những hạn chế khác nhau vốn có trong ngôn ngữ này, khiến tôi mất tập trung vào bản chất của lập trình.

Tôi thậm chí còn không thử sử dụng C++, bởi vì... nó thậm chí còn phức tạp hơn. Python lại đến giải cứu.

Tôi muốn cảm ơn giám đốc điều hành nền tảng Andrei Repyakh, nơi đã mang lại cho tôi sự tự do hoàn toàn, khuyến khích các thử nghiệm của tôi.

Để chắc chắn rằng mình không bỏ sót điều gì, tôi đã thử một ngôn ngữ khác - Ruby (trang web của dự án, nhưng sau đó quay lại với Python. Ruby, giống như Perl, có rất nhiều cấu trúc mà chỉ những chuyên gia mới có thể đọc được, điều này không giúp ích gì cho những lập trình viên mới làm quen Và xét về số lượng module thì Python vẫn vượt trội hơn hẳn.

Để các em có thể tự học, tôi quyết định dịch cuốn sách Cách suy nghĩ như một nhà khoa học máy tính. Nhưng trong quá trình dịch, tôi luôn có ý muốn bổ sung ý kiến ​​của riêng mình, sắp xếp lại các chương để cách trình bày tài liệu logic hơn. Hơn nữa, tôi phát hiện ra nhiều vấn đề gây tranh cãi. Cuối cùng tôi đã viết cuốn sách của riêng mình, dựa trên Cách suy nghĩ như một nhà khoa học máy tính, nhưng có bổ sung và sửa đổi. Có thể nói đây là phiên bản tiếng Nga hoặc một nhánh của dự án.

Cuốn sách hóa ra phức tạp hơn một chút so với kế hoạch: nói chung, nó tương ứng với trình độ trung học và khóa học ban đầu Các trường đại học cũng như học sinh THCS, với sự hỗ trợ của giáo viên, cũng sẽ có thể nắm vững nội dung trong sách mà không gặp nhiều khó khăn.

Cuốn sách này được phân phối theo giấy phép OPL (với hạn chế VI-B), có nghĩa là nội dung trong cuốn sách này có thể được sử dụng tự do cho bất kỳ mục đích nào, ngoại trừ mục đích thương mại.

Bản sửa đổi: 170 Lời nói đầu Tất nhiên, các bản sao phi thương mại phải được phân phối có giấy phép và không thay đổi quyền tác giả của cuốn sách. Nếu không, bạn được trao quyền tự do hoàn toàn. Lấy nó. Sử dụng nó.

:) Bản sửa đổi: 170 Lời cảm ơn Lời cảm ơn Cuốn sách này được phân phối tự do như truyền miệng. Do đó, nó cũng được phát triển tự do, không bị hạn chế bởi bất kỳ giấy phép nào ngoài OPL. Cuốn sách này phần lớn có được sự đóng góp của những người được liệt kê ở đây:

X Shlykov Dmitry X Rudskikh Vyacheslav X Voloshin Evgeniy X Belchenko Alexander X Brechalov Dmitry X Otkidach Denis X Olishchuk Andrey X Churanov Mikhail X Pushilin Sergey X Litvinova Elena X Lipanin Anton X Zhukov Boris Rất cám ơn những người đam mê phong trào tự do phần mềm(sống khắp thế giới, vì những gì họ làm.

Đặc biệt xin cảm ơn nhóm dự án bộ ứng dụng văn phòng mở OpenOffice.org (vì sản phẩm tốt mà cuốn sách này được viết ra.

Ôn tập: 170 Giới thiệu Giới thiệu Ở trường, giáo viên hỏi học sinh bố mẹ các em làm gì. Cô gái đưa tay ra:

Bố tôi là bác sĩ.

Đây là một nghề tốt”, giáo viên nói.

“Và bố tôi là tài xế,” một cậu bé khoe.

Thật là một nghề thú vị. Bố bạn làm nghề gì? - giáo viên hỏi Vovochka và anh bình tĩnh trả lời:

Anh ấy chơi piano trong một nhà thổ.

Thầy bị sốc;

Cùng ngày hôm đó, cô đến nhà Vovochka và phẫn nộ nói với cha mình:

Làm sao bạn có thể nuôi dạy một đứa trẻ trong điều kiện như vậy?! Bạn có thực sự chơi piano trong nhà chứa không?!

Bố của Vovochka xấu hổ:

Bạn thấy đấy, tôi là một lập trình viên. Tôi chuyên về mạng TCP/IP, viết các ứng dụng mạng phân tán cho hệ điều hành UNIX, nhưng làm sao tôi có thể giải thích điều này cho một cậu bé bảy tuổi?

Nhìn từ bên ngoài, nghề lập trình viên (và bất kỳ chuyên gia máy tính nào khác) có lẽ trông hơi bí ẩn. Những người này đang làm gì? Họ ngồi trước máy tính cả ngày và kể cho nhau nghe những câu chuyện cười kỳ lạ - cho đến gần đây đây vẫn là cách mà hầu hết mọi người vẫn nghĩ. Nhưng ngày nay, công nghệ thông tin đã thâm nhập vào hầu hết các lĩnh vực hoạt động của con người: từ những thứ quen thuộc như điện thoại di động đến công nghệ vũ trụ. Máy tính đơn giản hóa công việc xử lý tài liệu và giúp tối ưu hóa quy trình kinh doanh. Nhờ những người kín đáo ngồi trước máy tính suốt đêm, chúng ta có thể giao tiếp trong thời gian thực với bạn bè và đối tác kinh doanh ở bất kỳ đâu trên thế giới bằng cách sử dụng Internet. Thiền sư nói: Công việc của thầy không thấy được.

Cuốn sách này nhằm mục đích dạy bạn không chỉ cách viết chương trình mà còn cả cách suy nghĩ như một chuyên gia máy tính. Cách suy nghĩ này kết hợp các phương pháp được sử dụng trong toán học, khoa học và kỹ thuật. Giống như các nhà toán học, các nhà khoa học máy tính sử dụng ngôn ngữ hình thức để ghi lại các ý tưởng, thuật toán và thao tác trên các đối tượng cụ thể. Giống như các kỹ sư, họ thiết kế các vật thể bằng cách lắp ráp các thành phần khác nhau vào hệ thống và chọn giải pháp từ các giải pháp thay thế khả thi. Giống như các nhà khoa học tự nhiên, họ nghiên cứu hành vi hệ thống phức tạp, xây dựng giả thuyết, tiến hành thí nghiệm.

Kỹ năng quan trọng nhất của một chuyên gia máy tính là khả năng giải quyết vấn đề. Kỹ năng này liên quan đến khả năng hình thành chúng, suy nghĩ sáng tạo về các giải pháp khả thi và truyền đạt rõ ràng phương án đã chọn. Hóa ra, học lập trình là cơ hội tuyệt vời để phát triển tất cả những kỹ năng này.

Vậy hãy bắt đầu. Bạn có thể đọc mô tả chi tiết về quá trình cài đặt trình thông dịch Python và mọi thứ bạn cần để làm việc với cuốn sách trong phần tiếp theo.

Bản sửa đổi: 170 Giới thiệu Bạn nên làm quen với nó trước khi chuyển sang học chương đầu tiên để không gặp khó khăn gì trong quá trình nắm vững tài liệu trong sách. Nhưng đừng quên rằng điều quan trọng nhất là ham học hỏi, khả năng đặt câu hỏi và tìm kiếm câu trả lời cho chúng.

z0.1. Kiến thức cơ bản Để nắm vững tài liệu trong cuốn sách này, bạn sẽ cần có những kỹ năng máy tính cơ bản, cụ thể là:

X Làm việc với các tập tin và thư mục (thư mục);

X Khởi chạy chương trình;

X Chỉnh sửa tập tin văn bản;

X Nếu bạn đã cài đặt hệ thống UNIX trên máy tính của mình, việc có thể làm việc trong bảng điều khiển sẽ rất hữu ích;

X Làm việc trên Internet - bạn có thể tìm thấy rất nhiều thông tin hữu ích ở đó;

X Ít nhất kiến ​​thức cơ bản về tiếng Anh sẽ rất hữu ích.

Hãy nhớ rằng các gói văn phòng (MS Office, OpenOffice.org, StarOffice và những thứ tương tự) sẽ không giúp bạn lập trình. Các chương trình được gõ bằng các trình soạn thảo văn bản đơn giản như MS Notepad (hay còn gọi là Notepad).

Thật tốt nếu bạn biết mã nhị phân là gì và biết cách chuyển đổi số từ hệ thống số này sang hệ thống số khác, tất cả những điều này thường được dạy trong các khóa học khoa học máy tính ở trường.

Việc cài đặt hệ điều hành nào trên máy tính của bạn không quan trọng - Python có các triển khai cho tất cả các nền tảng phổ biến nhất: Windows, UNIX (GNU/Linux, FreeBSD, v.v.) và thậm chí cả Mac OS X. Hơn nữa, các chương trình được viết trên cùng một nền tảng hệ điều hành , sẽ được thực thi thành công trên bất kỳ hệ điều hành nào khác nếu có cài đặt trình thông dịch Python!

Python được bao gồm trong hầu hết các bản phân phối GNU/Linux, nhưng đây không nhất thiết phải là phiên bản mới nhất. Vì vậy, bạn vẫn nên xem trang Python và đọc tin tức. Python, giống như hầu hết các dự án cộng đồng mã nguồn mở, đang phát triển rất năng động. Chúng tôi thực sự khuyên bạn nên sử dụng trình thông dịch Python phiên bản 2.3.3 trở lên - bản phát hành này đã sửa các lỗi gây khó khăn khi viết các chương trình không phải tiếng Anh.

Bây giờ chúng ta hãy xem xét kỹ hơn quá trình cài đặt trình thông dịch Python trên các hệ điều hành khác nhau.

z0.2. Tôi có thể lấy trình thông dịch Python ở đâu?

Trình thông dịch ngôn ngữ Python được phân phối miễn phí theo Giấy phép Python Software Foundation (PSF) (trong một số cách, thậm chí còn dân chủ hơn GNU GPL (Giấy phép Công cộng GNU:

Trang web chính thức của dự án ngôn ngữ Python có tại địa chỉ Tại đây, trong phần Tải xuống, bạn có thể tải xuống phiên bản mới nhất cho hệ điều hành của mình. Vì Các hệ thống giống UNIX Bản phân phối trình thông dịch có sẵn ở hai phiên bản: trong mã nguồn (archive.tar.gz), dưới dạng gói vòng/phút (.rpm, .src.rpm, được biên dịch cho bản phân phối của bạn) hoặc gói .deb (dành cho bản phân phối Debian Linux) . Đối với hệ điều hành Windows, hãy tải xuống tệp exe, tệp này chứa chính trình thông dịch và chương trình cài đặt.

Bản sửa đổi: 170 Giới thiệu z0.3. Cài đặt trình thông dịch ngôn ngữ Python trên UNIX Trong tất cả các hệ điều hành giống UNIX (bất kỳ hệ thống BSD nào, GNU/Linux, Solaris, v.v.), quá trình cài đặt nhìn chung sẽ giống nhau. Trong các bản phân phối GNU/Linux hỗ trợ hệ thống quản lý gói RPM, ngoài quy trình cài đặt UNIX tiêu chuẩn từ mã nguồn, bạn có thể cài đặt Python từ gói vòng/phút. Hơn nữa, trong các bản phân phối GNU/Linux dựa trên RPM (RedHat Linux, Mandrake, SuSE Linux, ASPLinux, ALTLinux), nên cài đặt Python từ vòng/phút.

Tải xuống bản phân phối Python và cài đặt nó cho phù hợp. Để làm điều này, bạn sẽ cần quyền siêu người dùng (root). Nếu bạn không có mật khẩu siêu người dùng thì rõ ràng bạn nên yêu cầu quản trị viên hệ thống đang bảo trì máy tính của bạn trợ giúp.

z0.3.1. Cài đặt/cập nhật Python từ gói vòng/phút Nếu bạn đăng nhập với tư cách người dùng không có đặc quyền, hãy chuyển sang chế độ siêu người dùng:

# Sau đó, đi đến thư mục chứa gói vòng/phút và gõ lệnh (có tính đến phiên bản Python bạn đã tải xuống):

#rpm -i python-x.x.rpm z0.3.2. Cài đặt Python từ mã nguồn Giải nén mã nguồn từ kho lưu trữ đã tải xuống:

$ gzip -cd python-x.x.tar.gz | tar xvf Chuyển đến thư mục nơi bản phân phối được giải nén và chạy lệnh:

$./configure Sau đó, bạn nên bắt đầu quá trình xây dựng Python:

$make Sau khi hoàn tất, bạn cần chuyển sang chế độ superuser và chạy lệnh make install:

# thực hiện cài đặt Trên thực tế, không có sự khác biệt nào ở đây so với cài đặt tiêu chuẩn từ mã nguồn cho các hệ điều hành giống UNIX. Trên hầu hết các hệ thống, bạn nên xây dựng phần mềm trong thư mục /usr/local/src/.

Bản sửa đổi: 170 Giới thiệu z0.4. Cài đặt Python trên hệ điều hành Cài đặt Windows Python trên Windows đơn giản hơn trên UNIX. Chỉ cần tải xuống tệp cài đặt (ví dụ: Python-2.3.3.exe), chạy nó trên máy của bạn và trả lời tất cả các câu hỏi trong chương trình cài đặt, hoàn thành câu trả lời bằng cách nhấp vào nút Tiếp theo.

Trước tiên, bạn cần chỉ định nơi cài đặt trình thông dịch. Theo mặc định, nó được đặt trong thư mục C:\PythonXX, trong đó XX là số phiên bản. Ở bước này, chỉ cần nhấp vào nút Tiếp theo.

Nếu bạn đang cài đặt Python lần đầu tiên, hãy chọn tùy chọn Không, không tạo bản sao lưu.

Bước tiếp theo là chọn các thành phần để cài đặt. Tốt hơn là nên kích hoạt cài đặt mọi thứ được cung cấp (bao gồm cả tài liệu). Bộ hoàn chỉnh chiếm khoảng 20 megabyte trên ổ cứng của bạn.

Cuối cùng, bạn cần đặt tên nhóm cho menu chính. Bạn chỉ cần nhấp vào Tiếp theo Chương trình sẽ hiển thị thông tin tóm tắt về những gì sẽ được cài đặt và ở đâu. Nhấn Next lần nữa và đợi quá trình cài đặt hoàn tất. Nhấn Finish để thoát khỏi trình cài đặt.

z0.5. Chạy các chương trình được viết bằng Python Để chạy một chương trình được viết bằng Python, trên hệ thống UNIX, bạn cần gọi trình thông dịch Python và chuyển nó dưới dạng tham số tên của tệp chứa chương trình sẽ được khởi chạy:

$ python my_program.py Ngoài ra, trên hệ điều hành UNIX, một chương trình có thể chỉ định trình thông dịch nào sẽ được gọi để thực thi nó. Để làm điều này, trong dòng đầu tiên của chương trình, bạn có thể viết:

#! /usr/bin/env python Sau đó, bạn cần tạo tệp có tập lệnh thực thi được:

$ chmod u+x my_program.py Sau này, tập lệnh có thể được thực thi bằng cách chỉ cần gõ tên của nó vào dòng lệnh:

$ my_program.py hoặc, nếu tùy chọn đầu tiên không hoạt động:

$./my_program.py Chuỗi ký tự #! các lập trình viên thường đọc nó là she-bang!.

Trong hệ điều hành chương trình Windowsđược viết bằng Python được khởi chạy theo cách thông thường - sử dụng Explorer để tìm tệp chứa chương trình và nhấp đúp vào biểu tượng của nó bằng nút chuột trái. Python, khi được cài đặt, sẽ liên kết phần mở rộng tệp .py với trình thông dịch Python, vì vậy việc nhấp đúp vào tệp đó sẽ khởi chạy Python, chương trình này sẽ thực thi chương trình được ghi trong tệp. Nếu chương trình của bạn không có giao diện đồ họa, hệ điều hành Windows sẽ mở một cửa sổ bảng điều khiển. Sau khi kết thúc chương trình, cửa sổ này sẽ đóng ngay lập tức nên bạn có thể không có thời gian để xem kết quả hoạt động của nó. Bạn có thể tránh điều này bằng cách thêm dòng sau vào cuối chương trình:

raw_input("Nhấn phím bất kỳ để thoát") Điều này sẽ buộc trình thông dịch phải đợi nhấn phím bất kỳ trước khi thoát khỏi chương trình.

Nếu bạn đã chỉ định một tiện ích mở rộng khác, phương thức khởi chạy nhấp đúp sẽ không hoạt động. Trên Windows, các chương trình Python phải luôn có phần mở rộng là .py hoặc .

ôi. Tùy chọn thứ hai khác ở chỗ Python khởi động một cách im lặng, nghĩa là không cần mở cửa sổ bảng điều khiển. Tiện ích mở rộng .pyw được khuyến nghị cho các chương trình có giao diện đồ họa và hoàn toàn không yêu cầu cửa sổ bảng điều khiển.

Một tùy chọn khác là mở cửa sổ phiên MS-DOS (hoặc chạy FAR) và chạy lệnh sau:

C:\Examples> python my_program.py Với lệnh này, chúng ta khởi chạy trình thông dịch Python và cho nó biết chương trình sẽ thực thi tệp nào.

z0.6. Môi trường phát triển Gói Python tiêu chuẩn bao gồm môi trường phát triển tích hợp IDLE, trong đó các chương trình chỉnh sửa sẽ thuận tiện hơn nhiều so với một trình soạn thảo văn bản đơn giản. IDLE được viết bằng Python sử dụng thư viện Tcl độc lập với nền tảng, vì vậy nó có thể dễ dàng chạy trên bất kỳ hệ điều hành nào có triển khai Python. IDLE còn có hệ thống gỡ lỗi tích hợp cho phép bạn chạy từng dòng chương trình, giúp tìm lỗi dễ dàng hơn. Nếu vì lý do nào đó IDLE không phù hợp với bạn, bạn có thể thử các môi trường phát triển khác.

Hệ thống UNIX có nhiều trình soạn thảo có những ưu điểm và nhược điểm riêng, cả trình soạn thảo bảng điều khiển (vi, emacs, trình soạn thảo mc tích hợp) và trình soạn thảo đồ họa (vim, emacs, kate, trình soạn thảo IDLE, v.v.).

Lựa chọn dễ dàng nhất có thể là Kate - nó được bao gồm trong các phiên bản mới nhất của môi trường cửa sổ KDE. Kate có thể làm nổi bật cú pháp chương trình, có trình mô phỏng bảng điều khiển tích hợp và một mô-đun đặc biệt giúp làm việc với các chương trình được viết bằng Python dễ dàng hơn: trình duyệt mã, được kích hoạt thông qua menu Cài đặt trong phần Mô-đun ứng dụng.

Một trình soạn thảo thú vị khác: SciTE (Ngoài việc đánh dấu, nó có thể thu gọn các khối văn bản, điều này hỗ trợ rất nhiều cho công việc khi làm việc với các chương trình lớn, nhưng không có trình duyệt mã (ít nhất là trong gói tiêu chuẩn), ngoài ra, SciTE vẫn cần phải được Nga hóa, điều này có thể gây ra một số khó khăn cho người mới bắt đầu.

Để lập trình Python trên Windows, cũng có một số trình soạn thảo và môi trường tốt ngoài IDLE.

Đầu tiên, đây là PythonWin - một môi trường phát triển Python rất tốt cho Windows (có thể tải xuống từ trang web PythonWin nổi bật bởi không có vấn đề với các ký tự tiếng Nga, môi trường lập trình thuận tiện và tích hợp với hệ điều hành.

Bản sửa đổi: 170 Giới thiệu Chúng tôi cũng có thể giới thiệu trình soạn thảo UniRed (bạn có thể tải xuống từ trang web. Đây là trình soạn thảo văn bản tuyệt vời dành cho Windows 95/98/NT/2000/XP, hiểu cả cú pháp Python và tất cả các bảng mã có thể có (bao gồm tất cả Cyrillic và tất cả các bảng mã thuộc họ Unicode).

Cuối cùng, nó rất hữu ích cho việc phát triển và chạy các chương trình quản lý tập tin XA. Bất kỳ ai đã từng làm việc với Norton hoặc Volkov Commander đều sẽ thành thạo FAR.

Trình soạn thảo tích hợp hiểu cả hai bảng mã tiếng Nga được sử dụng trong Windows và bản thân trình quản lý thuận tiện hơn nhiều khi chạy các chương trình bảng điều khiển so với cửa sổ DOS tiêu chuẩn. Trên hệ điều hành Windows, FAR có lẽ là môi trường phù hợp nhất để chạy các chương trình Python.

Bây giờ chúng ta đã được trang bị đầy đủ và sẵn sàng bắt đầu học lập trình bằng Python. Hãy chuyển sang chương tiếp theo, bao gồm các khái niệm cơ bản.

Ôn tập: 170 Khái niệm cơ bản Chương 1. Khái niệm cơ bản Đầu tiên, bạn sẽ phải hiểu một số khái niệm cơ bản. Không cần phải ghi nhớ chúng - chỉ cần hiểu chúng ít nhất ở mức độ trực quan là đủ. Sau này bạn sẽ bắt đầu sử dụng chúng trong thực tế và mọi thứ sẽ đâu vào đấy. Đây có lẽ là một trong những phần tẻ nhạt nhất của cuốn sách.

h1.1. Thuật toán và chương trình Khái niệm thuật toán là một trong những khái niệm trung tâm của toàn bộ ngành máy tính. Về bản chất, từ thuật toán đồng nghĩa với từ phương pháp hoặc công thức. Theo nghĩa này, chúng ta có thể nói về một thuật toán tìm nghiệm của một phương trình từ các hệ số của nó, hoặc về một thuật toán phân rã số tự nhiên thành các thừa số nguyên tố. Nếu các thuật toán dựa trên những phép tính đơn giản, thì các thuật toán như vậy được gọi là số. Tuy nhiên, các thuật toán phi số cũng được xem xét khá thường xuyên. Ví dụ: chuỗi ký hiệu: văn bản, công thức, v.v. có thể đóng vai trò là dữ liệu nguồn và kết quả. Vai trò của các phép toán không phải là các phép toán cộng, nhân và tương tự thông thường mà là các phép toán nối chuỗi hoặc các phép toán thay thế một số ký tự bằng các ký tự khác theo một bảng tương ứng nào đó. Một ví dụ là mã hóa văn bản bằng mã Morse. Có các thuật toán để xây dựng các đối tượng đồ họa phức tạp và chuyển đổi chúng. Để dạy máy tính làm một việc gì đó, trước tiên bạn phải tạo ra một thuật toán.

Thuật toán là một phương pháp được mô tả chi tiết để thu được kết quả thỏa mãn các điều kiện đã đặt dựa trên dữ liệu ban đầu.

Chương trình là một chuỗi các lệnh máy mô tả một thuật toán.

Tất nhiên, để viết được một chương trình, bạn cần phải đưa ra một thuật toán.

Các chương trình máy tính thường được viết bằng các ngôn ngữ lập trình đặc biệt.

h1.2. Ngôn ngữ lập trình và mức độ trừu tượng Có một số cách tiếp cận lập trình. Ban đầu, các phép tính được mô tả ở cấp độ hướng dẫn máy bằng mã nhị phân. Hợp lý chương trình tương tự khá khó nắm bắt do thực tế là người lập trình phải chú ý đến các vấn đề như, chẳng hạn như cần phân bổ bao nhiêu vị trí bộ nhớ để lưu trữ một giá trị cụ thể. Để cộng hai số, trước tiên cần tính địa chỉ của các ô nhớ lưu trữ giá trị cộng và chỉ sau đó mới thực hiện thao tác cộng số nhị phân. Cách tiếp cận lập trình này đôi khi được gọi là dựa trên địa chỉ.

Rất khó để đọc và hiểu cách hoạt động của một chương trình viết bằng mã nhị phân chứ đừng nói đến việc tìm và sửa lỗi trong đó. Vì vậy, để đơn giản hóa công việc của mình, các lập trình viên đã nghĩ ra các mã ghi nhớ (từ tiếng Hy Lạp Mnemonikos mnemon - ghi nhớ) hoặc ghi nhớ - ký hiệu các chữ cái của lệnh máy nhị phân dễ nhớ hơn các chuỗi số 0 và số 1. Để đơn giản hóa việc làm việc với các ô nhớ, khái niệm biến bắt đầu được sử dụng.

Biến - trong lập trình, là ký hiệu chữ cái của vùng bộ nhớ trong đó một giá trị nhất định được lưu trữ.

Ôn tập: 170 Khái niệm cơ bản Để dịch các mã ghi nhớ thành các lệnh máy và tên biến thành địa chỉ của các ô nhớ, một chương trình đặc biệt đã được sử dụng - một trình dịch. Ngôn ngữ mã ghi nhớ được gọi là trình biên dịch mã.

Các công nghệ phát triển tiếp tục phát triển, các chuyên gia tìm kiếm những cách tiếp cận mới, và chẳng bao lâu sau, các ý tưởng bắt đầu kết tinh, sau này hình thành nên nền tảng của cái gọi là cách tiếp cận cấu trúc. Người ta nhận thấy rằng tất cả các phép tính được rút gọn thành các hành động cơ bản sau:

X Nhập dữ liệu từ bàn phím, từ tập tin hoặc từ bất kỳ thiết bị nào;

X Xuất dữ liệu ra màn hình, tập tin, máy in hoặc thiết bị khác;

X Thực hiện một số thao tác trên số, chuỗi hoặc các đối tượng khác;

X Chọn nhánh thực hiện chương trình dựa trên quyết định đã đưa ra (ví dụ: dựa trên kết quả so sánh hai giá trị);

X Lặp lại một nhóm thao tác, thường xuyên nhất là thay đổi một hoặc nhiều tham số.

Bạn sẽ sớm thấy rằng đây thực sự là trường hợp. Đồng thời, các dịch giả mới bắt đầu xuất hiện đã chuyển đổi các chương trình được viết bằng ngôn ngữ dựa trên các thao tác cơ bản này thành hướng dẫn máy. Những ngôn ngữ như vậy bắt đầu được gọi là ngôn ngữ cấu trúc hoặc ngôn ngữ cấp độ cao. Chương trình dành cho ngôn ngữ cấp cao mô tả quá trình tính toán ở mức độ trừu tượng cao hơn, tức là cho phép lập trình viên trừu tượng hóa các tính năng của việc triển khai máy.

Hãy minh họa điều này bằng hai ví dụ đơn giản. Chương trình đầu tiên bắt chước ngôn ngữ cấp thấp và chương trình thứ hai bắt chước ngôn ngữ cấp cao:

1. Nhập địa chỉ của số đầu tiên vào thanh ghi edx Nhập vào thanh ghi bộ đếm Nhập vào thanh ghi eax Nhãn lp:

So sánh giá trị của thanh ghi eax với giá trị được lưu tại địa chỉ lấy từ thanh ghi edx. Nếu nó nhỏ hơn hoặc bằng thì chuyển đến nhãn l_next. Ghi vào thanh ghi eax giá trị từ ô có địa chỉ được lưu trong edx. Nhãn l_next:

Thêm vào giá trị của thanh ghi edx Nếu thanh ghi bộ đếm khác 0 thì giảm giá trị trong thanh ghi bộ đếm đi 1 và chuyển đến nhãn lp Ghi giá trị từ thanh ghi eax vào biến Max 2. Ghi vào biến Max Lặp lại cho đến khi biến i thay đổi từ 1 đến 10 giây bước +1:

Nếu số thứ i lớn hơn Max thì đặt nó vào biến Max và xuất ra giá trị của biến Max.

Ôn tập: 170 Khái niệm cơ bản Cả hai chương trình đều tìm tối đa mười số tự nhiên cho trước.

Tên của các hoạt động đã được thay đổi thành tên tương ứng bằng tiếng Nga (phương pháp viết này đôi khi được gọi là mã giả), nhưng ý nghĩa của các hành động vẫn được giữ nguyên nên không khó để hiểu sự khác biệt của chúng.

Thông thường, các chương trình được viết bằng ngôn ngữ cấp cao hoạt động chậm hơn, bởi vì... người dịch không xây dựng tối ưu nhất mã máy theo văn bản chương trình. Nhưng các ngôn ngữ cấp cao có nhiều ưu điểm: chúng dễ đọc và dễ hiểu hơn và cũng có thể mang theo được. Điều này có nghĩa là các chương trình cấp cao có thể chạy trên các loại máy tính hoặc hệ điều hành khác nhau mà không cần hoặc ít sửa đổi, trong khi các chương trình cấp thấp thường được viết cho một loại máy tính hoặc hệ điều hành cụ thể và để chuyển các chương trình đó, chúng phải viết lại sang nền tảng khác.

Xin lưu ý rằng trong chương trình đầu tiên, kết quả không được in. Phương thức rút tiền chương trình cấp thấp sẽ thay đổi tùy thuộc vào nền tảng mà nó sẽ được thực thi chương trình này. Hơn nữa, chương trình này cũng sẽ không thể hoạt động trên bộ xử lý Intel 80286, vì thanh ghi edx và eax chỉ xuất hiện trong Intel 80386.

Các ngôn ngữ có cấu trúc cổ điển là C1 và Pascal. Chúng cho phép bạn mô tả các quá trình tính toán ở mức độ trừu tượng cao hơn so với các trình biên dịch mã, tuy nhiên, chúng có một số nhược điểm. Đặc biệt, một lập trình viên viết bằng các ngôn ngữ này vẫn phải xác định rõ ràng loại biến mà chương trình của anh ta sẽ hoạt động để người dịch biết cần phân bổ bao nhiêu bộ nhớ để lưu trữ chúng.

Ngoài ra, không thể lưu trữ, chẳng hạn như một chuỗi trong các biến được thiết kế để lưu trữ số nguyên.

Gần đây, cái gọi là ngôn ngữ cấp rất cao đã bắt đầu trở nên phổ biến. Chúng cho phép bạn trừu tượng hóa các loại biến, mở ra những khả năng mới. Chúng ta sẽ làm quen với chúng khi chúng ta nghiên cứu. Ngôn ngữ Python, là một trong những đại diện của nhóm ngôn ngữ lập trình này.

h1.3. Ngôn ngữ hình thức và tự nhiên Hãy cùng tìm hiểu xem ngôn ngữ lập trình khác với ngôn ngữ của chúng ta như thế nào tiếng mẹ đẻ, mà chúng ta đã nói từ khi còn nhỏ. Có hai loại ngôn ngữ: tự nhiên và hình thức.

Ngôn ngữ tự nhiên bao gồm các ngôn ngữ được con người sử dụng: tiếng Nga, tiếng Anh, tiếng Pháp, tiếng Ả Rập và các ngôn ngữ khác. Rất có thể, chúng nảy sinh một cách tự nhiên khi vào thời cổ đại con người cố gắng giải thích điều gì đó cho nhau. Tất cả chúng đều khá phức tạp, mặc dù chúng ta thường không nhận thấy điều đó. Để đơn giản hóa việc học ngoại ngữ, người ta đã đưa ra các quy tắc và từ điển trong đó các từ của một ngôn ngữ này tương đương với các từ của ngôn ngữ khác. Tiếng Phạn được coi là ngôn ngữ tự nhiên phức tạp nhất: bộ sưu tập đầu tiên các quy tắc tiếng Phạn (ngữ pháp của Panini, được gọi là Octateuch, thế kỷ thứ 4 trước Công nguyên) chứa hơn 4.000 quy tắc ngữ pháp. Tiếng Phạn có các trường hợp, 3 con số trong tên, hàng trăm dạng lời nói và lời nói, đồng thời có các phương tiện để hình thành tự do nhiều từ phái sinh. Ngoài ra, trong tiếng Phạn, bạn có thể tìm thấy tới vài chục từ tượng trưng cho cùng một đối tượng, nhưng phản ánh các sắc thái ý nghĩa khác nhau, do đó khả năng diễn đạt của nó thường vượt quá nhu cầu trung bình.

1 Đọc là si.

Ôn tập: 170 Khái niệm cơ bản Một trong những khái niệm cơ bản nhất ngôn ngữ đơn giản Ngôn ngữ bạn có thể nói là Esperanto.

Esperanto được phát minh bởi bác sĩ nhãn khoa Lazar (Ludovik) Markovich Zamenhof vào thế kỷ 19.

Ngay từ khi còn nhỏ, Zamenhof đã có ý tưởng rằng một ngôn ngữ chung sẽ giúp mọi người hiểu nhau hơn và tôn trọng nhau hơn.

Zamenhof có khả năng ngôn ngữ xuất sắc, và khi còn là một cậu học sinh, ngoài tiếng mẹ đẻ là tiếng Nga, tiếng Ba Lan và tiếng Yiddish, anh còn học tiếng Đức, tiếng Pháp, tiếng Anh, tiếng Latin, tiếng Hy Lạp cổ, tiếng Do Thái - tổng cộng khoảng mười bốn ngôn ngữ. Ông nhanh chóng bị thuyết phục rằng cả ngôn ngữ cổ và hiện đại đều không phù hợp làm ngôn ngữ thông thường. Sau đó ông quyết định tạo Ngôn ngữ mới, không thuộc về một dân tộc nào, sẽ dễ học nhưng đồng thời không thua kém các ngôn ngữ dân tộc về tính linh hoạt và biểu cảm. Và anh ấy đã thành công - toàn bộ ngữ pháp của Esperanto (cùng với các quy tắc ngữ âm) nằm gọn trên hai trang in, tất cả các từ đều mang tính quốc tế và về khả năng diễn đạt, Esperanto không hề thua kém (và ở một khía cạnh nào đó, thậm chí còn vượt trội hơn) so với tiếng Nga. Esperanto estas tre interesa kaj esprima lingvo.

Esperanto có thể được gọi là ngôn ngữ tự nhiên? Tôi nghĩ không có. Mặc dù có cuộc sống riêng và phát triển một cách tự nhiên nhưng ngữ pháp của Esperanto vẫn được hình thức hóa chặt chẽ. Vì vậy, nó đề cập đến các ngôn ngữ hình thức.

Ngôn ngữ hình thức là ngôn ngữ được con người phát minh ra để giải quyết các vấn đề cụ thể. Ví dụ, một tập hợp các ký hiệu và quy tắc đặc biệt để viết công thức được các nhà toán học sử dụng để viết công thức và chứng minh các định lý là một ngôn ngữ hình thức.

Các nhà hóa học cũng sử dụng ngôn ngữ trang trọng của mình để viết ra cấu trúc hóa học của các chất. Ngôn ngữ lập trình là ngôn ngữ hình thức được thiết kế để mô tả các thuật toán.

Ngôn ngữ hình thức được đặc trưng bởi có quy tắc cú pháp rõ ràng.

Ví dụ: 3+3=6 là ký hiệu toán học đúng về mặt cú pháp, nhưng 3=+6$ thì không. H2O là công thức hóa học đúng về mặt cú pháp của một chất, nhưng 2Zz thì không.

Khi bạn đọc một câu bằng tiếng Nga hoặc một cách diễn đạt bằng ngôn ngữ trang trọng, bạn xác định cấu trúc của nó, thường là một cách vô thức. Quá trình này được gọi là phân tích cú pháp hoặc phân tích cú pháp. Thuật ngữ tiếng Anh tương đương là phân tích cú pháp.

Ví dụ: khi đọc cụm từ Mẹ giặt khung, bạn dùng khoảng trắng để xác định đầu và cuối của từ và chỉ sau đó mới tìm chủ ngữ (lmama) và vị ngữ (lmyla). Sau khi phân tích cấu trúc cú pháp, bạn có thể hiểu ý nghĩa của nó - ngữ nghĩa.

Trước khi chuyển đổi một chương trình sang dạng mà máy tính có thể hiểu được, bất kỳ người dịch nào cũng phải thực hiện phân tích cú pháp. Trong quá trình phân tích cú pháp, người dịch phân tích cấu trúc cú pháp của biểu thức và tìm ra cái gọi là ký hiệu (mã thông báo) - những phần không thể phân chia về mặt cú pháp. Trong bối cảnh này, các ký hiệu có thể là tên của các biến, số, ký hiệu phép tính, từ khóa và tên gọi của các nguyên tố hóa học.

Việc sử dụng ký hiệu $ trong công thức 3=+6$ không có ý nghĩa gì, đó là một trong những lý do tại sao nó không đúng về mặt toán học. Vấn đề tương tự tồn tại trong công thức hóa học Zz: không có nguyên tố nào trong bảng tuần hoàn có ký hiệu Zz.

Loại lỗi cú pháp thứ hai có liên quan đến cấu trúc biểu thức không chính xác, tức là.

trình tự các ký tự. Biểu thức 3=+6$ có cấu trúc sai, vì Dấu cộng không thể ngay sau dấu bằng. Tương tự như vậy, công thức phân tử sử dụng chỉ số dưới, nhưng chúng không thể đứng trước nguyên tố hóa học.

Ôn tập: 170 Khái niệm cơ bản Mặc dù ngôn ngữ hình thức và ngôn ngữ tự nhiên có nhiều điểm chung nhưng chúng có một số điểm khác biệt quan trọng:

1. Tính rõ ràng Ngôn ngữ tự nhiên có nhiều thành ngữ, ẩn dụ;

Thông thường mọi người xác định ý nghĩa của các cụm từ tùy thuộc vào tình huống chúng được sử dụng. Ngôn ngữ hình thức được thiết kế để đảm bảo rằng các biểu thức không mơ hồ. Điều này có nghĩa là một biểu thức chỉ được có một nghĩa, bất kể ngữ cảnh.

2. Sự dư thừa Để loại bỏ sự mơ hồ và tránh hiểu lầm, ngôn ngữ tự nhiên sử dụng sự dư thừa: định nghĩa và bổ sung.

Ngôn ngữ hình thức ngắn gọn và biểu cảm tối đa.

Hầu hết những người quen với ngôn ngữ tự nhiên thường gặp khó khăn khi làm quen với các ngôn ngữ hình thức (bao gồm cả chương trình). Nhưng điều đáng ghi nhớ là mật độ ý nghĩa trong các ngôn ngữ như vậy lớn hơn, do đó chúng được đọc và hiểu chậm hơn. Cấu trúc rất quan trọng trong các ngôn ngữ hình thức, vì vậy đọc từ phải sang trái hoặc từ dưới lên trên không phải là cách tốt nhất để hiểu chúng. Và cuối cùng, những điều nhỏ nhặt cũng quan trọng. Những lỗi chính tả và dấu câu nhỏ (và cả lỗi chính tả), có thể bị bỏ qua trong các ngôn ngữ tự nhiên, sẽ có tác động lớn trong các ngôn ngữ trang trọng, thậm chí làm thay đổi nghĩa sang ngược lại.

Trong toán học có cả một phần dành cho lý thuyết về ngôn ngữ hình thức. Bộ máy phân tích cú pháp của người dịch dựa trên bộ máy toán học của lý thuyết này.

h1.4. Trình thông dịch và trình biên dịch Có hai loại trình dịch chuyển đổi mã nguồn chương trình thành các lệnh máy: trình thông dịch và trình biên dịch. Trình thông dịch đọc chương trình cấp cao (hoặc mã nguồn) và tương tác trực tiếp với hệ điều hành để thực thi chương trình đó. Việc chuyển đổi và thực thi chương trình được thực hiện theo từng dòng.

Nguồn kết quả Hoạt động Hệ thống chương trình mã thực thi trình thông dịch Không giống như trình thông dịch, trình biên dịch chuyển đổi hoàn toàn mã nguồn của chương trình thành mã máy (hay còn gọi là mã đối tượng), mà hệ điều hành có thể tự thực thi. Điều này cho phép các chương trình đã biên dịch chạy ngay cả trên các máy tính không có trình biên dịch.

Ngoài ra, các chương trình như vậy chạy nhanh hơn do máy tính không phải phân tích cú pháp và chuyển đổi nó thành dạng mà nó hiểu được mỗi lần trước khi khởi động chương trình.

Kết quả đối tượng Mã chương trình hệ thống mã thực thi Trình biên dịch hoạt động ban đầu (có thể thực thi) Tuy nhiên, các trình thông dịch hiện đại cũng có khả năng lưu trữ mã trung gian, việc thực thi mã này tốn ít thời gian hơn do tiết kiệm được việc phân tích mã nguồn. Tuy nhiên, đoạn mã trung gian như vậy chỉ có thể hiểu được. Bản sửa đổi: 170 Khái niệm cơ bản chỉ dành cho người thông dịch, vì vậy để chạy chương trình vẫn cần phải có nó trên máy tính.

Phải nói rằng với sức mạnh máy tính và dung lượng bộ nhớ hiện đại, sự khác biệt về tốc độ thực thi chương trình của trình thông dịch và trình biên dịch gần như không thể nhận thấy, nhưng quá trình phát triển và gỡ lỗi chương trình bằng ngôn ngữ thông dịch lại đơn giản hơn rất nhiều2.

Ngôn ngữ Python được thông dịch vì... các chương trình viết trên đó được thực thi bởi một trình thông dịch.

Có một dự án thú vị dành cho phiên bản Windows của Python: py2exe, cho phép bạn tạo các tệp exe độc ​​lập từ các tập lệnh.

Trên thực tế, py2exe bản thân nó không phải là một trình biên dịch - nó chuyển đổi tập lệnh thành mã trung gian bằng chính Python và đặt phần cần thiết của trình thông dịch vào tệp thực thi, cùng với mã trung gian này và mã của tất cả các mô-đun được sử dụng trong chương trình.

Vì vậy, bạn nhận được một tệp exe và một hoặc nhiều tệp dll chứa chương trình của bạn cùng với môi trường thời gian chạy. Bây giờ bạn không cần trình thông dịch Python riêng để chạy chương trình này.

Tuy nhiên, tệp thực thi thu được chỉ có thể chạy trong hệ điều hành Windows. Nếu chương trình của bạn chỉ nhằm mục đích chạy trên hệ thống đó và bạn không muốn yêu cầu người dùng cài đặt Python thì py2exe có thể là một công cụ rất hữu ích.

Lấy Thông tin thêm và bạn có thể tải xuống py2exe tại đây:

z1.5. Chương trình đầu tiên Đã đến lúc khởi chạy trình thông dịch Python và viết chương trình đầu tiên.

Có hai cách để sử dụng trình thông dịch: chế độ lệnh và chế độ thực thi từ tệp. Nếu bạn gõ một lệnh trên dòng lệnh của trình thông dịch Python, trình thông dịch sẽ hiển thị ngay kết quả thực hiện của nó:

$ python Python 2.3+ (#1, ngày 23 tháng 9 năm 2003, 23:07:16) trên linux Nhập "trợ giúp", "bản quyền", "tín dụng" hoặc "giấy phép" để biết thêm thông tin.

>>> in "Xin chào thế giới!" Chào thế giới!

Dòng đầu tiên của ví dụ là lệnh khởi động trình thông dịch Python trên hệ điều hành UNIX. Trong hệ điều hành Windows, để gọi trình thông dịch, chỉ cần gọi môi trường phát triển IDLE trong menu Bắt đầu chương trình. Hai dòng tiếp theo là thông tin từ trình thông dịch (số phiên bản, bản quyền - vì vậy 2 ngôn ngữ Biên dịch vẫn không thể thiếu trong các hệ thống thời gian thực, trong đó chỉ một sự chậm trễ nhỏ nhất cũng có thể dẫn đến thảm họa (ví dụ: các hệ thống như vậy dùng để điều khiển điều khiển tàu vũ trụ và dòng chảy của các quá trình vật lý phức tạp trong điều kiện phòng thí nghiệm và sản xuất).

Sửa đổi: 170 khái niệm cơ bản được trình bày). Lệnh thứ tư bắt đầu bằng dấu nhắc trình thông dịch >>>, cho biết rằng nó đã sẵn sàng thực thi các lệnh. Chúng tôi đã gõ lệnh in "Xin chào thế giới!", tức là. được hướng dẫn hiển thị dòng "Xin chào thế giới!" trên màn hình và hàng tiếp theo thông dịch viên xuất ra những gì chúng tôi yêu cầu.

Chúng ta cũng có thể viết chương trình vào một tệp và sử dụng trình thông dịch để thực thi nó. Tệp như vậy được gọi là script hoặc script (từ script tiếng Anh - script). Ví dụ: sử dụng trình soạn thảo văn bản, tạo tệp prog1.py có nội dung sau:

in "Xin chào thế giới!" Thông thường, tên của các tệp chứa chương trình Python sẽ kết thúc bằng chuỗi ký hiệu .py (những người làm việc trong hệ điều hành hệ thống DOS hoặc Windows sẽ gọi nó là phần mở rộng). Để thực thi chương trình, chúng ta phải chuyển tên của tập lệnh cho trình thông dịch dưới dạng tham số:

$ python prog1.py Xin chào thế giới!

Trong các môi trường phần mềm khác, phương pháp khởi động chương trình có thể khác, nhưng nguyên tắc gọi trình thông dịch sẽ vẫn như cũ.

Bài tập. Hãy thử thay đổi chương trình đầu tiên của bạn để nó chứa lỗi cú pháp: đầu tiên là lỗi liên quan đến đơn vị cú pháp không được nhận dạng (tức là một từ không xác định) và sau đó là lỗi liên quan đến cấu trúc chương trình không chính xác (bạn có thể thử đổi đơn vị cú pháp).

Cuộc thí nghiệm.

h1.6. Gỡ lỗi là gì?

Lập trình là một quá trình khá phức tạp và việc một lập trình viên mắc lỗi là điều khá tự nhiên. Chuyện đã xảy ra như vậy lỗi phần mềm gọi là bug (từ tiếng Anh bug - bug). Bạn sẽ không tìm thấy từ này trong tài liệu tiếng Nga, nhưng trong tiếng lóng của lập trình viên, nó được sử dụng khá thường xuyên cùng với từ trục trặc. Quá trình tìm kiếm và loại bỏ lỗi trong tài liệu tiếng Anh thường được gọi là gỡ lỗi, nhưng chúng ta sẽ gọi đó là gỡ lỗi.

Có ba loại lỗi có thể xảy ra trong chương trình:

lỗi cú pháp, lỗi thời gian chạy và lỗi ngữ nghĩa. Để tìm và sửa chúng nhanh hơn, bạn nên học cách phân biệt giữa chúng.

h1.6.1. Lỗi cú pháp Bất kỳ trình thông dịch nào cũng chỉ có thể thực thi một chương trình nếu chương trình đó đúng về mặt cú pháp. Theo đó, trình biên dịch cũng sẽ không thể chuyển đổi chương trình thành các lệnh máy nếu chương trình có lỗi cú pháp. Khi người dịch phát hiện ra lỗi (tức là gặp một hướng dẫn mà nó không thể hiểu được), nó sẽ làm gián đoạn công việc của mình và hiển thị thông báo lỗi.

Đối với hầu hết người đọc, lỗi cú pháp không phải là vấn đề lớn. Ví dụ, thường có những bài thơ không có dấu câu, nhưng chúng ta có thể dễ dàng đọc chúng, mặc dù điều này thường tạo ra sự mơ hồ trong cách giải thích chúng. Nhưng Bản sửa đổi: 170 Người dịch các khái niệm cơ bản (và trình thông dịch Python cũng không ngoại lệ) rất kén chọn các lỗi cú pháp.

Ngay cả khi Python tìm thấy ngay cả một lỗi đánh máy nhỏ trong chương trình của bạn, nó sẽ ngay lập tức hiển thị một thông báo cho bạn biết nó tìm thấy ở đâu và thoát ra. Anh ta sẽ không thể thực hiện một chương trình như vậy và do đó sẽ từ chối nó. Trong những tuần đầu tiên thực hành phát triển phần mềm, bạn có thể sẽ dành nhiều thời gian để tìm kiếm các lỗi cú pháp. Khi bạn có được kinh nghiệm, bạn sẽ ngày càng thừa nhận chúng ít hơn và tìm thấy chúng nhanh hơn.

h1.6.2. Lỗi thời gian chạy Loại lỗi thứ hai thường xảy ra trong quá trình thực thi chương trình (chúng thường được gọi là ngoại lệ hoặc nói tóm lại là ngoại lệ). Những lỗi như vậy có lý do khác. Nếu một ngoại lệ xảy ra trong một chương trình, điều đó có nghĩa là có điều gì đó không mong muốn đã xảy ra trong quá trình thực thi: ví dụ: một giá trị không chính xác được truyền vào chương trình hoặc chương trình đã cố chia một số giá trị cho 0, điều này không thể chấp nhận được theo quan điểm của rời rạc. toán học. Nếu hệ điều hành gửi yêu cầu chấm dứt chương trình ngay lập tức thì một ngoại lệ cũng sẽ được đưa ra. Nhưng trong các chương trình đơn giản, điều này khá hiếm khi xảy ra nên bạn có thể không gặp phải chúng ngay lập tức.

h1.6.3. Lỗi ngữ nghĩa Loại lỗi thứ ba là lỗi ngữ nghĩa. Dấu hiệu đầu tiên cho thấy chương trình của bạn có lỗi ngữ nghĩa là nó thực thi thành công, tức là. không có ngoại lệ, nhưng không làm những gì bạn mong đợi.

Trong những trường hợp như vậy, vấn đề là ngữ nghĩa của chương trình viết khác với những gì bạn nghĩ. Việc tìm ra những lỗi như vậy là một nhiệm vụ không hề đơn giản, bởi vì...

bạn phải nhìn vào kết quả của chương trình và tìm hiểu xem chương trình thực sự làm gì.

h1.6.4. Quá trình gỡ lỗi Trục trặc cũ tốt hơn hai trục trặc mới.

Lập trình viên nổi tiếng có câu nói Khả năng gỡ lỗi chương trình đối với một lập trình viên là một kỹ năng rất quan trọng.

Quá trình gỡ lỗi đòi hỏi rất nhiều nỗ lực và sự tập trung tinh thần, nhưng đó là một trong những điều thú vị nhất để làm.

Gỡ lỗi rất giống với công việc của một nhà khoa học tự nhiên. Bằng cách nghiên cứu kết quả của thử nghiệm trước đó, bạn rút ra một số kết luận, sau đó thay đổi chương trình cho phù hợp, chạy chương trình và bắt đầu phân tích lại kết quả.

Nếu kết quả thu được không trùng với kết quả mong đợi thì bạn sẽ phải hiểu lại nguyên nhân dẫn đến những khác biệt này. Nếu giả thuyết của bạn hóa ra là đúng, thì bạn sẽ có thể dự đoán kết quả của việc sửa đổi chương trình và sẽ tiến một bước gần hơn đến việc hoàn thành công việc trên đó, hoặc có lẽ nó sẽ khiến bạn càng bị thuyết phục hơn về sự ảo tưởng của mình.

Do đó, để kiểm tra chức năng của một chương trình, việc kiểm tra nó một lần là chưa đủ - bạn cần phải đưa ra tất cả các bộ dữ liệu đầu vào có thể có bằng cách nào đó có thể ảnh hưởng đến sự ổn định của hệ thống của bạn. Những tập hợp dữ liệu đầu vào như vậy được gọi là giá trị biên.

Đôi khi quá trình viết và gỡ lỗi chương trình không chỉ được phân chia theo thời gian mà còn được phân chia giữa các thành viên trong nhóm phát triển. Nhưng gần đây, cái gọi là phương pháp phát triển linh hoạt ngày càng trở nên phổ biến. Trong đó, mã hóa không tách rời khỏi việc gỡ lỗi: các lập trình viên viết mã cũng chịu trách nhiệm chuẩn bị các bài kiểm tra và xác định càng nhiều lỗi càng tốt trong quá trình mã hóa. Điều này cho phép họ tận hưởng trọn vẹn công việc của mình.

Nhân Linux, có mã nguồn gồm hàng triệu dòng, khởi đầu là một chương trình đơn giản, Linus Torvalds(Linus Torvalds) đã nghiên cứu khả năng thực hiện song song các tác vụ trên bộ xử lý Intel 80386. Một trong những chương trình đầu tiên của Linus là chương trình chuyển đổi giữa hai quy trình: in các chuỗi AAAA và BBBB. Chương trình này sau này trở thành Linux (Larry Greenfield, Phiên bản Beta 1 Hướng dẫn sử dụng Linux dành cho người dùng Linux).

Vì vậy, lập trình là một quá trình tinh chỉnh và sửa lỗi dần dần cho đến khi chương trình thực hiện được những gì chúng ta mong muốn. Bạn nên bắt đầu với một chương trình đơn giản thực hiện điều gì đó đơn giản, sau đó bạn có thể bắt đầu xây dựng chức năng của nó bằng cách thực hiện các sửa đổi nhỏ và gỡ lỗi các đoạn mã được thêm vào.

Bằng cách này, ở mỗi bước, bạn sẽ có một chương trình làm việc, ở một mức độ nào đó, chương trình này sẽ cho phép bạn đánh giá xem bạn đã làm được bao nhiêu công việc.

Trong các chương tiếp theo, bạn sẽ có cơ hội thực hành các chương trình gỡ lỗi.

Một số mẹo gỡ lỗi hữu ích có trong Phụ lục A - hãy nhớ đọc nó khi bạn có thời gian rảnh, tốt nhất là vào cuối phần nghiên cứu của chương thứ sáu.

Ôn tập: 170 Biến, phép tính và biểu thức Chương 2. Biến, phép tính và biểu thức Và cuối cùng, chúng ta đi vào lập trình thực tế. Bạn có thể khởi chạy ngay trình thông dịch Python. Sẽ không có hại gì nếu bạn kiểm tra các ví dụ trên máy tính của mình và thử nghiệm chúng. Nếu bạn tìm thấy bất kỳ lỗi hoặc lỗi đánh máy nào, hãy viết thư cho [email được bảo vệ]. Có lẽ tên của bạn sẽ xuất hiện trong danh sách những người phát triển sách.

h2.1. Giá trị và Loại Tất cả các chương trình đều hoạt động với các giá trị. Giá trị có thể là một số hoặc một chuỗi.

Ví dụ: trong chương trình đầu tiên, chúng ta đã in giá trị chuỗi "Xin chào thế giới!" trên màn hình. Theo cách tương tự, chúng ta có thể xuất ra số:

>>> in "Xin chào thế giới!" và 12 thuộc về nhiều loại khác nhau: str (từ chuỗi tiếng Anh - string) và int (từ số nguyên tiếng Anh - số nguyên)3. Trình thông dịch phân biệt một chuỗi với một số bằng dấu ngoặc kép kèm theo nó.

Nếu có số nguyên thì theo lý thuyết cũng phải có phân số. Hãy thử lệnh này:

>>> print 2, 2 Đây là ví dụ đầu tiên về lỗi ngữ nghĩa: chúng tôi dự kiến ​​trình thông dịch sẽ in một số thập phân, nhưng nó lại nhầm dấu phẩy là dấu phân cách giữa hai số nguyên và in chúng cách nhau bằng dấu cách. Nói chung, anh ấy đã hiểu nhầm chúng tôi, vì dấu phân cách là phân số và toàn bộ bộ phận các số trong Python, cũng như trong hầu hết các ngôn ngữ lập trình khác, là dot4:

>>> print 2. 2. Nếu bạn không chắc chắn về loại giá trị, bạn có thể kiểm tra nó như thế này:

>>> type("Xin chào thế giới!") >>> type(12) >>> type(2.4) Kiểu chuỗi được gọi là str trong Python, kiểu số nguyên được gọi là int và kiểu phân số là float (từ Số dấu phẩy động tiếng Anh - số dấu phẩy động).

3 Trong một số phiên bản Python, các kiểu này được gọi là không rút gọn: chuỗi và số nguyên.

4 Phương pháp bất thường này đối với chúng ta để tách phần nguyên và phần phân số là tiêu chuẩn của Mỹ để viết phân số thập phân.

Ôn tập: 170 Bài tập về biến, phép tính và biểu thức. Tự mình tiến hành thí nghiệm sau: kiểm tra loại giá trị "12" và "2.4"? Chúng là loại gì và tại sao?

Bài tập. Điều gì xảy ra nếu bạn cố gắng chuyển đổi chuỗi "8,53" thành số nguyên bằng hàm int()? Làm thế nào để giải quyết vấn đề này?

h2.2. Chuyển đổi kiểu Trong phần trước chúng ta đã học cách hiển thị số nguyên - việc này khá dễ thực hiện phải không? Nhưng đối với người phiên dịch, nhiệm vụ này có vẻ phức tạp hơn một chút, bởi vì nó phải chuyển đổi chúng thành chuỗi trước khi xuất ra các giá trị số.

Một lập trình viên cũng có thể làm điều này - Python có cả một tập hợp các hàm dựng sẵn có thể chuyển đổi các giá trị của loại này sang loại khác. Ví dụ: hàm int() chuyển đổi một giá trị thành kiểu số nguyên. Nếu việc chuyển đổi không thể được thực hiện, một ngoại lệ sẽ được đưa ra:

>>> int("32") >>> int("Hello") Traceback (cuộc gọi gần đây nhất gần đây nhất):

Tệp "", dòng 1, ở ?

ValueError: chữ không hợp lệ cho int(): Xin chào Hàm int() có thể chuyển sang số nguyên và số phân số, nhưng hãy nhớ rằng nó chỉ loại bỏ khi chuyển đổi phần phân đoạn:

>>> int(3.99999) >>> int(-2.3) - Hàm float() chuyển đổi số nguyên và chuỗi thành kiểu phân số.

>>> float(32) 32. >>> float("3.14159") 3. Và cuối cùng, hàm str() chịu trách nhiệm chuyển đổi sang kiểu chuỗi. Đây là những gì lệnh in chạy trước:

>>> str(32) "32" >>> str(3.14149) "3.14149" Bản sửa đổi: 170 Biến, phép toán và biểu thức Có vẻ lạ khi Python phân biệt số nguyên 1 với phân số 1.0: nó là cùng một số, nhưng thuộc về các loại khác nhau. Thực tế là loại giá trị quyết định cách nó được lưu trữ trong bộ nhớ.

h2.3. Biến Giống như bất kỳ ngôn ngữ lập trình nào khác, Python hỗ trợ khái niệm biến, nhưng có một chút khác biệt. Nếu trong C++ hoặc Pascal, biến là tên của vị trí bộ nhớ trong đó giá trị được lưu trữ thì trong Python, biến là tham chiếu đến vị trí bộ nhớ. Thoạt nhìn, sự khác biệt là không đáng kể, nhưng trên thực tế, đó là một cách tiếp cận hơi khác trong việc tổ chức lưu trữ các đối tượng trong bộ nhớ. Tuy nhiên, hiện tại chúng tôi không đặc biệt quan tâm đến điều này.

Để ghi nhớ một giá trị, bạn chỉ cần gán nó cho một biến. Việc này được thực hiện bằng cách sử dụng toán tử gán đặc biệt, được biểu thị bằng dấu bằng (=).

>>> tin nhắn = "Xin chào thế giới!" >>> n = >>> pi = 3. V trong ví dụ này biến message được gán (hoặc ánh xạ) thành "Xin chào thế giới!", biến n được gán giá trị 12 và biến pi được gán giá trị 3.14159.

Cách dễ nhất biểu diễn đồ họa biến: viết tên biến, vẽ mũi tên, đầu kia thêm giá trị được gán.

Những hình vẽ như vậy đôi khi được gọi là sơ đồ trạng thái vì chúng đại diện cho trạng thái của biến, tức là giá trị nào hiện được gán cho nó.

tin nhắn УHello world!Ф n pi 3. Lệnh in cũng hoạt động với các biến:

>>> in tin nhắn Xin chào thế giới!

>>> print n >>> print pi 3. Như bạn có thể thấy, lệnh print không in tên các biến mà in giá trị của chúng. Các biến, giống như giá trị, có một loại. Hãy kiểm tra điều này bằng hàm type():

>>> type(message) >>> type(n) >>> type(pi) Bản sửa đổi: 170 Biến, phép toán và biểu thức Kiểu của một biến giống với kiểu của giá trị được gán cho nó. Hãy xem một ví dụ khác:

>>> tin nhắn = "Xin chào thế giới!" >>> n = >>> type(message) >>> message = n >>> print message >>> type(message) Ví dụ này thú vị vì hai lý do. Đầu tiên, nó sử dụng khả năng gán giá trị của một biến cho một biến khác. Cấu trúc message = n hoạt động tương tự như việc gán giá trị cho một biến: biến message được gán giá trị của biến n. Trong trường hợp này, giá trị 12 chỉ được lưu trong bộ nhớ một lần - Python sử dụng bộ nhớ khá tiết kiệm.

message УXin chào thế giới! Ф n Thứ hai, như có thể thấy từ ví dụ, biến thông báo, sau khi gán giá trị n cho nó, đã thay đổi kiểu của nó. Không phải mọi ngôn ngữ lập trình đều có thể làm được điều này một cách dễ dàng.

h2.4. Tên biến và từ khóa Như Frederick P. Brooks, Jr.5 đã lưu ý, điều thú vị nhất khi trở thành một lập trình viên là anh ta làm việc với các ý tưởng ở dạng thuần túy nhất của chúng: anh ta viết những ý tưởng trừu tượng bằng các ngôn ngữ hình thức để chúng biến công việc thành hiện thực. người khác dễ dàng hơn.

Để biến một ý tưởng trừu tượng, chưa thể hiện trong thế giới vật chất, thành mã chương trình, cần phải xác định các thực thể và hành động, đặt tên cho chúng để quản lý chúng và truy tìm mối liên hệ giữa chúng với các thuộc tính của chúng. Bạn có thể đoán rằng tên của các thực thể mà người lập trình làm việc cùng là các biến. Vì vậy, việc chọn tên biến có ý nghĩa là điều đáng làm.

Tên biến có thể có độ dài tùy ý, nhưng hãy cố gắng chọn tên không quá ngắn cũng không quá dài - khả năng đọc chương trình phụ thuộc vào điều này.

Khi soạn tên biến trong Python, bạn có thể sử dụng bất kỳ chữ cái, số Latin nào và dấu _ (dấu gạch dưới). Dấu gạch dưới có thể được sử dụng cho 5 Frederick P. Brooks, Jr. đã lãnh đạo dự án IBM OS/360 nổi tiếng;

ông là tác giả của nguyên tắc Không có Viên đạn Bạc (NSB - Không có Viên đạn Bạc, với ý nghĩa là một phương tiện phổ quát để chống lại các dự án quái vật). Chúng ta đang nói về cuốn sách Tháng con người huyền thoại của anh ấy, hay cách các hệ thống phần mềm được tạo ra.

Ôn tập: 170 Biến, phép tính và biểu thức phân tách các từ tạo nên tên biến: ví dụ user_name hoặc full_price. Nhưng tên biến không thể bắt đầu bằng số.

>>> 1message = "Xin chào thế giới!" Tệp " ", dòng 1tin nhắn = "Xin chào thế giới!" ^ SyntaxError: cú pháp không hợp lệ >>> price_in_$ = File " ", dòng price_in_$ = ^ SyntaxError: cú pháp không hợp lệ >>>>", line>

>>> print = "Some message" File " ", line print = "Some message" ^ SyntaxError: cú pháp không hợp lệ Đây là một tình huống quen thuộc phải không? Hãy phân tích những gì chúng tôi nhận được. Chúng tôi đã thử sử dụng lệnh in làm tên biến và nhận được lỗi tương tự, nghĩa là từ>

Thật vậy, những từ>

Tổng số phiên bản trong Python là 2.3. 29 từ khóa được bảo lưu:

Bản sửa đổi: 170 Các biến, phép toán và biểu thức và del for được nâng lên khẳng định Elif từ lambda return break else toàn cục không thử>

Cũng xin lưu ý rằng thông dịch viên phân biệt giữa chữ in hoa và chữ nhỏ, tức là

tin nhắn và Tin nhắn sẽ là các biến khác nhau.

Bài tập. Viết chương trình xác minh rằng trình thông dịch Python phân biệt chữ thường và chữ thường chữ in hoa trong tên biến.

h2.5. Biểu thức Trong chương đầu tiên, chúng ta đã biết khái niệm biểu thức ở dạng tổng quát và sử dụng chúng trong chương trình. Hãy định nghĩa thuật ngữ này. Biểu thức là một chuỗi các đơn vị cú pháp mô tả một hành động cơ bản trong ngôn ngữ lập trình. Ví dụ: in "Xin chào thế giới!" và tin nhắn = n là các biểu thức.

Khi bạn nhập một biểu thức trên dòng lệnh, trình thông dịch sẽ thực thi biểu thức đó và in kết quả, nếu có. Kết quả của biểu thức in "Xin chào thế giới!" là dòng: Xin chào thế giới!. Biểu thức gán không tạo ra gì cả.

Các tập lệnh thường chứa một chuỗi các biểu thức và kết quả của các biểu thức được in ra khi chúng được thực thi. Ví dụ: hãy chạy tập lệnh chứa các biểu thức sau:

print x = print x Tập lệnh này sẽ xuất ra kết quả như sau:

Một lần nữa, biểu thức gán không tạo ra bất kỳ đầu ra nào.

h2.6. Thực thi biểu thức Về cơ bản, biểu thức là một chuỗi các giá trị, biến và toán tử.

Nếu bạn viết một biểu thức, trình thông dịch sẽ thực thi nó và hiển thị:

>>> 1 + Bản thân giá trị được coi là một biểu thức, giống như một biến:

Bản sửa đổi: 170 Biến, phép tính và biểu thức >>> x = >>> x Nhưng việc thực thi và xuất ra kết quả của việc thực thi một biểu thức không hoàn toàn giống nhau:

>>> tin nhắn = "Xin chào thế giới!" >>> tin nhắn "Xin chào thế giới!" >>> in tin nhắn Xin chào thế giới!

Khi Python xuất giá trị của một biểu thức ở chế độ lệnh, nó sẽ sử dụng cùng định dạng được sử dụng khi nhập giá trị đó. Ví dụ: khi xuất chuỗi, nó sẽ đặt chúng trong dấu ngoặc kép. Lệnh in cũng in giá trị của một biểu thức, nhưng trong trường hợp chuỗi, nó in nội dung của chuỗi mà không có dấu ngoặc kép.

Trong các tập lệnh, các biểu thức hoàn toàn không xuất ra bất cứ thứ gì trừ khi chúng chứa câu lệnh in.

Ví dụ: tập lệnh sau không xuất ra một dòng nào:

3. "Xin chào Thế giới!" 1 + Bài tập. Sửa đổi tập lệnh từ ví dụ trước để nó in giá trị của cả bốn biểu thức.

Trong chế độ lệnh, trình thông dịch Python lưu trữ kết quả của biểu thức cuối cùng trong một biến đặc biệt _ (gạch dưới). Bạn có thể xem kết quả của biểu thức cuối cùng và sử dụng nó trong biểu thức của mình:

>>> 1,25 + 2. >>> in _ 2. >>> 5 + _ 7. Do đó, Python khá thuận tiện khi sử dụng như một máy tính đơn giản. Trong các phần sau, chúng ta sẽ hiểu những thao tác nào trình thông dịch Python có thể thực hiện.

Ôn tập: 170 Biến, phép tính và biểu thức 32.7. Toán tử và toán hạng Toán tử là các ký tự đặc biệt (hoặc chuỗi ký tự) đại diện cho các phép toán nhất định. Ví dụ: dấu + biểu thị phép cộng và dấu * biểu thị phép nhân. Các giá trị mà thao tác được thực hiện được gọi là toán hạng.

Tất cả các biểu thức sau đây đều đúng theo quan điểm của Python:

20+32 giờ-1 giờ*60+phút/60 5**2 (5+9)*(15-7) Ý nghĩa của hầu hết chúng không khó hiểu. Ý nghĩa của các ký hiệu +, -, * và / trong Python cũng giống như trong toán học. Dấu ngoặc đơn được sử dụng để nhóm các phép toán và hai dấu hoa thị (**) biểu thị phép tính lũy thừa.

Nếu toán hạng là một biến thì trước khi biểu thức được ước tính, giá trị mà biến trỏ đến sẽ được thay thế vào vị trí của nó.

Phép cộng, trừ, nhân và lũy thừa hoạt động giống như cách chúng ta quen thuộc, nhưng phép chia hoạt động hơi khác một chút. Ví dụ sau đây minh họa điều này:

>>> phút = >>> phút/ Giá trị của biến phút là 59;

Kết quả của phép chia 59 cho 60 phải là 0,98333 chứ không phải 0. Lý do cho sự khác biệt này là do Python thực hiện phép chia số nguyên.

Khi cả hai toán hạng đều là số nguyên và Python giả định rằng kết quả cũng phải là số nguyên. Vì vậy, phép chia số nguyên luôn loại bỏ phần phân số.

Làm thế nào để có được kết quả phân số? Chỉ cần chuyển đổi mạnh mẽ một trong các toán hạng thành số phân số là đủ:

>>> phút = >>> float(phút) / 0. Tùy chọn khác:

>>> phút = >>> phút / 60. 0. Nếu một trong các toán hạng thuộc về kiểu phao, thì cái thứ hai sẽ tự động được chuyển đổi sang loại này, thành loại phức tạp hơn.

h2.8. Thứ tự các toán tử Hầu hết các ngôn ngữ lập trình đều cho phép bạn nhóm nhiều toán tử trong một biểu thức. Điều này rất thuận tiện, ví dụ: nếu bạn cần tính tỷ lệ phần trăm của hai đại lượng:

Bản sửa đổi: 170 Biến, phép tính và biểu thức >>> in 100 * 20 / 80, "%" 25% Ví dụ này tính tỷ lệ phần trăm của hai số: 20 và 80. Sau kết quả của biểu thức, ký hiệu % được hiển thị - biểu tượng trình thông dịch tính toán biểu thức số học và hiển thị kết quả, sau đó thêm dòng sau dấu phẩy.

Khi có nhiều toán tử trong một biểu thức, trình tự các thao tác sẽ phụ thuộc vào thứ tự chúng xuất hiện trong biểu thức cũng như mức độ ưu tiên của chúng. Mức độ ưu tiên của các toán tử trong Python hoàn toàn trùng khớp với mức độ ưu tiên của các phép toán.

Ưu tiên cao nhất được dành cho dấu ngoặc đơn, cho phép bạn thay đổi trình tự thao tác. Vì vậy, các thao tác trong ngoặc đơn được thực hiện trước tiên.

Ví dụ: 2*(3-1) bằng 4, (1+1)**(5-2) bằng 8. Cũng thuận tiện khi sử dụng dấu ngoặc đơn để làm cho biểu thức dễ đọc hơn, ngay cả khi chúng hiện diện trong biểu thức không ảnh hưởng đến kết quả: (100*20)/80.

Ưu tiên tiếp theo là phép tính lũy thừa, vì vậy 2**1+1 là 3 chứ không phải 4 và biểu thức 3*1**3 sẽ cho kết quả là 3 chứ không phải 27.

Phép nhân và phép chia có cùng mức độ ưu tiên, cao hơn phép cộng và phép trừ. 2*3-1 bằng 5, không phải 4;

2/3-1 là -1, không phải 1 (kết quả của phép chia số nguyên là 2/3=0).

Các toán tử có cùng mức ưu tiên được thực hiện từ trái sang phải. Vì vậy, trong biểu thức 100*20/80, phép nhân được thực hiện trước (biểu thức trở thành 2000/80);

sau đó phép chia được thực hiện, dẫn đến giá trị là 25. Nếu các phép toán được thực hiện từ phải sang trái thì kết quả sẽ khác.

Bài tập. Thay đổi biểu thức 100*20/80 để trình tự các phép tính được đảo ngược. Bạn nhận được kết quả gì sau khi thực hiện và tại sao?

h2.9. Các thao tác đơn giản trên chuỗi Nói chung, bạn không thể thực hiện các thao tác tương tự trên chuỗi như trên số, vì vậy các ví dụ sau sẽ không thực hiện được:

message-1 "Xin chào"/123 "Xin chào"*"thế giới!" "15"+ Nhưng toán tử + hoạt động với các chuỗi, mặc dù nó biểu thị một phép toán khác: nối hoặc ghép các chuỗi.

>>> str1 = "Xin chào" >>> str2 = "thế giới" >>> print str1 + str2 + "!" Chào thế giới!

Lưu ý rằng dòng thứ hai bắt đầu bằng khoảng trắng. Không gian là một ký tự giống như bất kỳ ký tự nào khác.

Toán tử * cũng có thể được sử dụng với chuỗi, nhưng chỉ khi một trong các toán hạng là số nguyên. Trong trường hợp này, toán tử * tượng trưng cho thao tác lặp lại chuỗi (hoặc phép lặp). Ví dụ: "Fun"*3 sẽ cho ra kết quả "FunFunFun".

Bản sửa đổi: 170 Biến, phép toán và biểu thức Bạn có thể theo dõi sự tương tự giữa các phép toán trên số và các phép toán trên chuỗi: giống như 4*3 tương đương với 4+4+4, "Fun"*3 tương đương với "Fun"+"Fun "+"Vui vẻ ".

Nhưng mặt khác, nối và lặp lại có một số khác biệt đáng kể so với phép cộng và phép nhân.

Bài tập. Tất cả các phép toán trong toán học được phân loại theo tính chất của chúng (tính giao hoán, tính kết hợp, v.v.). Phép cộng và phép nhân có những tính chất nào mà phép nối và phép lặp không có?

Đừng lười biếng tra cứu sách tham khảo toán học - hiểu được tính chất của các đồ vật mà bạn thao tác sẽ mang lại cho bạn những lợi thế lớn.

Bài tập. Sẽ thu được kết quả gì sau khi thực hiện biểu thức "hello"+"world"*3? Có thể rút ra kết luận gì dựa trên kết quả này?

h2.10. Bố cục Cuối cùng, chúng ta hãy xem xét một khái niệm quan trọng khác: bố cục. Không để ý, chúng ta đã gặp phải nó rồi.

Toàn bộ thế giới xung quanh chúng ta bao gồm các bộ phận cấu thành. Ví dụ, những ngôi nhà được làm bằng gạch hoặc các khối xây dựng, gạch lại được làm từ những hạt cát nhỏ và gạch được làm từ các phân tử và nguyên tử. Để mô hình hóa các hiện tượng trong thế giới xung quanh, một công cụ xây dựng mô hình cũng phải có khả năng lắp ráp các vật thể nhỏ thành các hệ thống, từ đó sẽ được kết hợp thành các phức hợp thậm chí còn phức tạp hơn.

Một công cụ mô hình hóa (tức là mô tả các đồ vật khác nhau và tình huống) đối với một lập trình viên là các ngôn ngữ lập trình. Tất cả các ngôn ngữ cấp cao đều triển khai khả năng tạo hệ thống từ các phần tử hoặc thành phần đơn giản hơn.

Ví dụ: chúng ta biết cách cộng hai số và cách hiển thị giá trị kết quả.

Vì vậy, chúng ta có thể làm điều đó trong một biểu thức:

>>> print 17 + Trên thực tế, việc cộng và xuất của một giá trị không xảy ra cùng một lúc: biểu thức được ước tính trước, sau đó kết quả mới là đầu ra. Nhưng bạn có thể xuất kết quả của bất kỳ biểu thức nào theo cách này, bất kể nó phức tạp đến mức nào.

Biểu thức có thể được xây dựng từ các biểu thức khác theo nhiều cách.

Hãy xem xét ví dụ này:

>>> tỷ lệ phần trăm = 100 * 20/80;

phần trăm in Đầu tiên, các biểu thức có thể được lồng vào nhau. Đặc biệt, biểu thức gán có cấu trúc sao cho bên trái dấu gán phải có tên của biến mà kết quả đánh giá biểu thức ở bên phải của toán tử gán được gán. Đổi lại, biểu thức ở vế phải cũng phức tạp:

việc tính toán được thực hiện theo thứ tự được xác định bởi mức độ ưu tiên của các hoạt động. Phép chia trong ví dụ của chúng tôi lấy kết quả của phép nhân làm toán hạng đầu tiên - đây cũng là một ví dụ về biểu thức lồng nhau.

Phần sửa đổi: 170 Biến, phép tính và biểu thức Sau đây là tùy chọn thứ hai để sắp xếp biểu thức. Trong ví dụ này, hai biểu thức (biểu thức gán và biểu thức hiển thị giá trị của biến phần trăm) được phân tách bằng dấu chấm phẩy. Các biểu thức này được thực hiện lần lượt. Nói chung, bất kỳ chương trình nào cũng là một chuỗi các biểu thức. Nếu các biểu thức nằm trên các dòng riêng biệt thì không nhất thiết phải đặt dấu chấm phẩy ở cuối mỗi biểu thức: in trong trường hợp này Dấu phân cách biểu thức là dấu kết thúc dòng. Quy tắc này áp dụng cho Python, nhưng trong C++ và Pascal, biểu thức phải kết thúc bằng dấu chấm phẩy.

Sau này bạn sẽ thấy rằng sự kết hợp có thể được sử dụng để kết hợp bất kỳ đơn vị cú pháp và biểu thức nào, kể cả các lệnh gọi chương trình con.

Bài tập. Hãy thử chạy lệnh trên dòng lệnh trình thông dịch Python: 100 * 20/80 = phần trăm. Bạn đã nhận được kết quả gì và tại sao?

Ôn tập: 170 Hàm Chương 3. Hàm h3.1. Các chương trình con Trở lại thời kỳ lập trình địa chỉ, người ta nhận thấy rằng một số phần của chương trình có thể được sử dụng nhiều lần nếu giá trị của một số tham số bị thay đổi. Ví dụ: một chương trình có thể tính toán một giá trị bằng cách sử dụng một công thức nhất định nhiều lần, nhưng mỗi lần các giá trị được nhập vào công thức lại thay đổi.

Các lập trình viên bắt đầu khái quát hóa các giải pháp cho các bài toán con nhỏ, lặp lại và truy cập các phần của chương trình bằng các giải pháp này khi cần thiết. Các chương trình không còn tuyến tính nữa, nên chúng bắt đầu giống một gói mì ống, bởi vì... bao gồm các chuỗi hướng dẫn và việc chuyển đổi giữa chúng được thực hiện bằng cách sử dụng các lệnh chuyển đổi có điều kiện hoặc vô điều kiện và các nhãn xác định phần đầu của mỗi mì ống.

Ở một mức độ nào đó, điều này làm phức tạp đáng kể quá trình gỡ lỗi và mở rộng chức năng của chương trình, nhưng mặt khác, nó mở ra những cơ hội mới cho các lập trình viên: thứ nhất, các chương trình bắt đầu chiếm ít không gian hơn và chúng trở nên dễ điều hướng hơn;

thứ hai, việc sửa lỗi đã trở nên dễ dàng hơn nhiều, bởi vì các lập trình viên không còn cần phải tìm kiếm tất cả các phần của mã được lặp lại với những thay đổi nhỏ để sửa lỗi được tìm thấy ở một trong số chúng - chỉ cần sửa lỗi này ở một nơi là đủ.

Ý tưởng tái sử dụng mã rất quan trọng trong lập trình, bởi vì không có nó, sự hỗ trợ và phát triển của hiện đại sản phẩm phần mềm Với sự phức tạp của chúng, đây là một nhiệm vụ gần như không thể. Ít nhất, chi phí sở hữu các chương trình sẽ cao hơn nhiều nếu không có nó và việc sử dụng chúng sẽ không mang lại lợi nhuận trong hầu hết các trường hợp.

Ngôn ngữ lập trình có cấu trúc triển khai khái niệm tái sử dụng mã theo nhiều cách khác nhau. Một trong số đó là viết chương trình con.

Các chương trình con trình bày cùng một bộ hướng dẫn như chính chương trình, nhưng chúng giải quyết các vấn đề ít phức tạp hơn. Các chương trình con có thể nhận một bộ tham số nhất định làm đầu vào và trả về một số giá trị làm đầu ra.

TRONG ngôn ngữ Pascal Có hai loại chương trình con: thủ tục và hàm. Trong Python, cũng như trong C++, các chương trình con được triển khai ở dạng tổng quát hơn, do đó không có sự phân chia như vậy - trong các ngôn ngữ này chỉ có các hàm.

Đôi khi các chương trình con được nhóm thành cái gọi là mô-đun - các tệp đặc biệt lưu trữ mô tả về các chức năng này, có thể được kết nối và sử dụng trong bất kỳ phần nào của dự án hoặc thậm chí trong các dự án khác. Cách tạo và kết nối các mô-đun trong Python được mô tả chi tiết trong Phụ lục B. Nhưng bây giờ, hãy bắt đầu nắm vững các hàm.

Bản sửa đổi: 170 Chức năng 3.2. Lệnh gọi hàm Chúng ta đã gặp các lệnh gọi hàm khi xác định và chuyển đổi các loại giá trị và biến:

>>> type("Xin chào thế giới!") >>> int("32") Hàm xác định loại của một giá trị hoặc biến được gọi là type();

Giá trị hoặc biến cần chuyển đổi phải đặt sau tên hàm trong ngoặc đơn - đây được gọi là đối số của hàm. Như bạn có thể thấy từ ví dụ, hàm int() được gọi theo cách tương tự.

Như vậy, để gọi hàm, bạn chỉ cần gõ tên hàm và liệt kê các tham số trong ngoặc đơn, nếu không cần truyền tham số thì không cần phải viết gì trong ngoặc đơn. Ví dụ: trong hàm str() tham số đầu tiên là tùy chọn, tức là nó có thể được bỏ qua:

>>> str() "" 3.3. Hệ thống trợ giúp Python có nhiều hàm được xác định cho phép bạn giải quyết nhiều vấn đề khác nhau.

Một số trong số chúng được nhóm theo mục đích và được đặt trong các mô-đun riêng biệt. Trong phần tiếp theo, chúng ta sẽ tìm hiểu cách nhập mô-đun và sử dụng các hàm từ chúng, nhưng trước tiên, chúng ta sẽ tìm hiểu cách xác định chức năng của một hàm cụ thể.

Kỹ năng này sẽ rất hữu ích cho bạn trong tương lai, bởi vì... Thông thường rất khó để đoán mục đích của các chức năng chỉ bằng tên của chúng.

Để đơn giản hóa công việc của lập trình viên, Python cung cấp một tài liệu biến tích hợp (bắt đầu và kết thúc bằng các cặp dấu gạch dưới), thường lưu trữ thông tin tham khảo tối thiểu:

>>> print str.doc str(object) -> string Trả về một chuỗi biểu diễn đẹp của đối tượng.

Nếu đối số là một chuỗi thì giá trị trả về là cùng một đối tượng.

>>> Hàm str() tự giới thiệu và hiển thị thông tin về chính nó: nó lấy tham số gì, trả về loại giá trị nào và mô tả ngắn gọn chức năng của nó.

Bắt đầu với phiên bản 2.2, Python đã giới thiệu một hệ thống trợ giúp, được triển khai dưới dạng hàm help(). Hàm này lấy tên của bất kỳ đối tượng nào (bao gồm mô-đun hoặc hàm) làm tham số và hiển thị thông tin trợ giúp về đối tượng đó.

Bài tập. Thủ tục thanh toán thông tin lai lịch hàm str(). Xin lưu ý rằng hàm help() sẽ không hoạt động trong các phiên bản Python dưới 2.2. Thoát khỏi hệ thống trợ giúp bằng phím [Q].

Bản sửa đổi: 170 Hàm 3.4. Nhập mô-đun và hàm toán học Ngoài các phép toán đơn giản nhất trên các số mà chúng ta đã xem xét, Python có khả năng tính toán các giá trị phức tạp hơn hàm toán học:

lượng giác, logarit, v.v. Để truy cập các hàm này, bạn cần nhập hoặc kết nối một mô-đun đặc biệt trong đó lưu trữ định nghĩa của các hàm này. Bạn có thể làm điều này bằng cách sử dụng các hướng dẫn sau:

>>> nhập toán học >>> Lệnh này nhập mô-đun toán học. Python hỗ trợ nhập một phần mô-đun (bạn có thể đọc thêm về điều này trong Phụ lục B), nhưng chúng tôi chưa cần nó.

Vì vậy, chúng tôi đã nhập một mô-đun có mô tả các hàm toán học và bây giờ chúng tôi sẽ cố gắng gọi một trong số chúng từ mô-đun đó. Trước tiên, hãy xác định những hàm và hằng số nào được xác định trong mô-đun:

>>> dir(math) ["doc", "file", "name", "acos", "asin", "atan", "atan2", "ceil", "cos", "cosh", "e ", "exp", "fabs", "sàn", "fmod", "frexp", "hypot", "ldexp", "log", "log10", "modf", "pi", "pow", "sin", "sinh", "sqrt", "tan", "tanh"] >>> Do thực hiện lệnh này, trình thông dịch đã in tất cả các tên được xác định trong mô-đun này. Trong số đó có biến doc. Để truy cập một biến hoặc hàm từ một mô-đun đã nhập, bạn phải chỉ định tên của nó, đặt dấu chấm và viết tên bắt buộc:

>>> print math.doc Mô-đun này luôn có sẵn. Nó cung cấp quyền truy cập vào các hàm toán học được xác định theo tiêu chuẩn C.

>>> print math.pi 3. >>> decibel = math.log10(17.0) Dòng đầu tiên của ví dụ in mô tả về mô-đun;

thứ tư là giá trị của hằng số và thứ sáu tính giá trị logarit 17 trong cơ số 10. Ngoài logarit thập phân, mô-đun còn xác định logarit tự nhiên (tức là với cơ số e = 2.7182818284590451): math.log() . Một ví dụ nữa:

>>> chiều cao = math.sin(45) >>> in chiều cao 0. Nếu bạn đã học lượng giác, chắc hẳn bạn còn nhớ rằng sin của 45 độ bằng căn bậc hai của 2 chia cho 2. Hãy kiểm tra kết quả của phép tính tính toán hàm:

Bản sửa đổi: 170 Hàm >>> math.sqrt(2) / 2. 0. Kết quả đã khác. Tại sao? Phải chăng nhà phát triển đã mắc sai lầm? Rất có thể không ai tránh khỏi những sai lầm. Tuy nhiên, trước khi viết báo cáo lỗi và gửi cho nhà phát triển, chúng ta hãy xem trợ giúp cho chức năng này:

>>> help(math.sin) Trợ giúp về hàm sin có sẵn:

sin(...) sin(x) Trả về sin của x (tính bằng radian).

(END) Từ phần trợ giúp, bạn có thể thấy rằng các hàm lượng giác lấy giá trị góc tính bằng radian làm tham số. Nhấn [Q] để thoát khỏi hệ thống trợ giúp với cảm giác tự hào: bây giờ chúng ta đã biết hàm math.sin() hoạt động như thế nào;

Hãy chuyển đổi sang radian:

>>> độ = >>> góc = độ * math.pi / 180. >>> Height = math.sin(angle) >>> in chiều cao 0. Bây giờ kết quả đều giống nhau - mọi thứ đều chính xác.

Bài tập. Chạy các hướng dẫn sau trên dòng lệnh của trình thông dịch Python phiên bản 2.2 trở lên:

>>> nhập toán >>> in math.doc...

>>> help(math) Đọc mô tả của mô-đun và các chức năng của nó. Tất cả trợ giúp sẽ không vừa với màn hình nhưng bạn có thể cuộn qua văn bản bằng các phím mũi tên. Thoát khỏi hệ thống trợ giúp bằng phím [Q].

Nếu muốn, bạn có thể thử sử dụng các hàm này bằng cách viết một vài chương trình đơn giản sử dụng chúng. Chúng có thể được sử dụng ở đâu?

h3.5. Bố cục Trong chương thứ hai chúng ta đã xem xét bố cục liên quan đến các phép tính toán học và những cách diễn đạt đơn giản. Nhưng sự kết hợp cũng cho phép bạn kết hợp các lệnh gọi hàm: một hàm có thể lấy bất kỳ biểu thức nào trả về một giá trị nằm trong phạm vi định nghĩa của nó làm tham số;

mặt khác, một lệnh gọi hàm (chính xác hơn là kết quả thực thi của nó) có thể được sử dụng làm toán hạng:

>>> x = math.sin(math.asin(math.sqrt(2) / 2.0) + math.pi / 2) >>> print x 0. >>> Hãy xem ví dụ này. Thao tác đầu tiên mà trình phân tích cú pháp gặp phải khi phân tích biểu thức này là gán giá trị của biểu thức ở bên phải dấu = cho biến x. Trước khi gán, trình thông dịch phải đánh giá giá trị của biểu thức này, tức là. tính sin giá trị của biểu thức math.asin(math.sqrt (2) / 2.0) + math.pi / 2, lần lượt bằng tổng các giá trị của các biểu thức con math.asin(math .sqrt(2) / 2.0) và math.pi / 2. Hàm đầu tiên được tính theo cách tương tự: đầu tiên, giá trị của biểu thức trong dấu ngoặc đơn được tính, sau đó hàm math.asin() được gọi, mà biểu thức kết quả được truyền dưới dạng đối số. Biểu thức con thứ hai là /2. Sau khi tính tổng của hai biểu thức con này, trình thông dịch chuyển giá trị kết quả làm đối số cho hàm math.sin() và gán kết quả đó cho biến x.

Viết chương trình tính nghiệm của phương trình bậc hai ax2+bx+c=0, a0 từ các hệ số của phương trình này. Các hệ số phải được nhập vào đầu chương trình thành các biến a, b và c.

Hãy thử đặt các biến a, b và c lần lượt là 1, 0 và -1. Chương trình sẽ xuất ra các giá trị 1.0 và -1.0. Kiểm tra xem kết quả của bạn có như mong đợi không.

Khi thử nghiệm với các hệ số khác, hãy nhớ rằng có những phương trình không có nghiệm (những phương trình như vậy có phân biệt nhỏ hơn 0), vì vậy đừng lo lắng nếu một lỗi có dạng xuất hiện trong chương trình của bạn: ValueError: lỗi miền toán học. Một lát sau chúng ta sẽ tìm ra cách để tránh điều này.

h3.6. Tạo hàm Cho đến nay chúng ta đã sử dụng các hàm có sẵn của Python và các hàm từ các mô-đun đi kèm với Python. Nhưng sức mạnh của ngôn ngữ lập trình có cấu trúc là chúng ta có thể tạo ra các hàm của riêng mình và việc này được thực hiện khá đơn giản. TRONG lập trình có cấu trúc Hàm là một chuỗi các biểu thức được đặt tên để thực hiện một thao tác được yêu cầu. Python có toán tử định nghĩa hàm đặc biệt với cú pháp sau:

định nghĩa FUNCTION_NAME(PARAMETER_LIST):

TRÌNH TỰ BIỂU TƯỢNG Quy tắc chọn tên hàm hoàn toàn giống với quy tắc chọn tên biến được mô tả ở chương trước. Danh sách tham số xác định một tập hợp các giá trị có thể được truyền cho hàm dưới dạng dữ liệu đầu vào - các tham số được liệt kê cách nhau bằng dấu phẩy. Dòng đầu tiên của định nghĩa thường được gọi là tiêu đề hàm, ký hiệu là từ khóa def (từ tiếng Anh định nghĩa - để xác định). Tiêu đề hàm trong Python kết thúc bằng dấu hai chấm. Nó có thể được theo sau bởi bất kỳ số lượng biểu thức nào, nhưng chúng phải được viết lệch từ đầu dòng. Đối với Bản sửa đổi: 170 Các chức năng của phần bù như vậy, bạn có thể sử dụng một hoặc nhiều khoảng trắng, nhưng có lẽ thuận tiện nhất là sử dụng ký tự tab (phím) thay vì dấu cách. Hãy viết và kiểm tra hàm đầu tiên của chúng ta;

để hoàn thành chuỗi biểu thức tạo nên phần thân của hàm, chỉ cần nhấn lại phím (trong trình chỉnh sửa hỗ trợ tự động thụt lề, bạn cũng sẽ phải nhấn để xóa thụt lề được thêm tự động):

>>> def printAnything(object):

In đối tượng...

>>> printAnything("Some string") Some string >>> number = >>> printAnything(number) Trong hai dòng đầu tiên của ví dụ, chúng ta đã định nghĩa hàm PrintAnything() để in đối tượng được truyền dưới dạng tham số. Chúng ta có thể truyền một chuỗi hoặc một số cho hàm này, đó là điều chúng ta đã cố gắng thực hiện ở dòng thứ tư và thứ bảy của ví dụ.

Kết quả thu được trùng khớp với kết quả mong đợi, nhưng chúng ta đừng tập trung vào điều này và thực hiện một thử nghiệm khác.

Điều gì sẽ xảy ra nếu bạn chuyển tên hàm làm tham số? Hãy gọi PrintAnything(), cho biết tên của nó trong ngoặc đơn:

>>> printAnything(printAnything) >>> Python in thông tin về hàm: tên và địa chỉ trong bộ nhớ nơi nó được lưu trữ! Trong trường hợp này, địa chỉ là 0x80d7554, nhưng địa chỉ này trên máy tính của bạn có thể khác. Bây giờ hãy mở trình soạn thảo văn bản và viết một chương trình như thế này:

def printXin chào():

in "Xin chào!" def runFunction(function_name):

function_name() runFunction(printHello) Lưu chương trình trong một tệp có tên prog2.py và chạy nó từ dòng lệnh (trong hệ điều hành Windows, chỉ cần nhấp đúp chuột vào biểu tượng của tệp này6):

$ python prog2.py Xin chào!

6 Đừng quên viết lệnh chờ nhấn phím ở dòng cuối cùng của chương trình, như được mô tả trong phần Chạy các chương trình viết bằng Python (xem phần Giới thiệu).

Bản sửa đổi: 170 Hàm Có lẽ bạn đã hiểu Python đã làm gì khi chúng ta gọi hàm runFunction() và truyền cho nó tên của hàm printHello() làm tham số: nó thay thế function_name bằng giá trị của tham số đã truyền và do đó được gọi là printHello( ) chức năng. Đó là một ngôn ngữ lập trình hiếm có có được sự linh hoạt như vậy. Trong C++ hoặc Pascal, việc này được thực hiện một cách không hề tầm thường.

Ngoài ra, hãy nhớ rằng bạn không thể gọi một hàm trước khi nó được xác định - điều này sẽ tạo ra một ngoại lệ.

Bài tập. Chuyển đổi chương trình tính nghiệm của phương trình bậc hai thành hàm printRoots(). Các tham số của hàm này phải là các hệ số của đa thức bậc hai: a, b và c. Sau khi tính được các nghiệm của phương trình, hàm sẽ in chúng ra.

Bài tập. Viết hàm tính khoảng cách giữa hai điểm trên mặt phẳng (có tọa độ (x1, y1) và (x2, y2)).

khoảng cách x1, y1, x2, y2= x2 -x12 y2 - y 3.7. Tham số và đối số Cho đến nay, chúng ta đã học cách tạo các hàm của riêng mình và phân biệt giữa định nghĩa hàm và lệnh gọi hàm. Bây giờ hãy xác định thuật ngữ: sự khác biệt giữa tham số hàm và đối số của nó là gì? Có một sự khác biệt lớn, nhưng bạn có thể không nhận thấy nó.

Tham số của hàm là danh sách các biến được gán các giá trị được truyền khi gọi hàm này. Và bản thân các giá trị được truyền vào được gọi là đối số. Trong phần thân của nó, hàm hoạt động với các tham số chứ không phải với các đối số. Hãy xem một ví dụ từ phần trước:

>>> def printAnything(object):

In đối tượng...

>>> printAnything("Some string") Some string >>> number = >>> printAnything(number) Ở đây, đối tượng biến là tham số và chuỗi "Some string" và biến number là các đối số. Vì vậy, việc truyền một đối số hoặc truyền một giá trị làm tham số là đúng, nhưng không truyền tham số cho hàm. Cố gắng đừng nhầm lẫn những khái niệm này.

h3.8. Các biến cục bộ Hãy quay lại hàm PrintRoots() để tìm nghiệm của phương trình bậc hai. Nó trông giống như thế này:

def printRoots(a, b, c):

Bản sửa đổi: 170 Hàm D = b**2 - 4 * a * c import math x1 = (-b + math.sqrt(D)) / 2 * a x2 = (-b - math.sqrt(D)) / 2 * a print "x1 =", x1, "\nx2 =", x Chuỗi ký tự \n ở dòng cuối cùng của thân hàm hướng dẫn lệnh in đi tới dòng mới. Thân hàm xác định ba biến: D, x và x2. Các biến như vậy được gọi là cục bộ, bởi vì chúng chỉ có thể được truy cập trong chính thân hàm. Sau khi chức năng hoàn thành, chúng sẽ bị xóa khỏi bộ nhớ. Chương trình sau đây có thể minh họa điều này:

def printRoots(a, b, c):

D = b**2 - 4 * a * c nhập toán x1 = (-b + math.sqrt(D)) / 2 * a x2 = (-b - math.sqrt(D)) / 2 * a print " x1 =", x1, "\nx2 =", x printRoots(1.0, 0, -1.0) print D Nếu bạn chạy nó, trình thông dịch sẽ ngay lập tức hiển thị lỗi như thế này sau khi hàm PrintRoots() hoàn thành:

$ python prog5.py x1 = 1. x2 = -1. Traceback (cuộc gọi gần đây nhất):

Tệp "prog5.py", dòng 12, ở định dạng ?

print D NameError: tên "D" là không xác định Tại sao hành vi này được chọn? Bạn nghĩ như thế nào? Hãy sửa đổi chương trình của chúng tôi theo cách này:

def printRoots(a, b, c):

D = b**2 - 4 * a * c import math print "Trong hàm D = ", D x1 = (-b + math.sqrt(D)) / 2 * a x2 = (-b - math.sqrt( D)) / 2 * a print "x1 =", x1, "\nx2 =", x Phiên bản: 170 Hàm D = "test" print "Trước khi gọi hàm D = ", D printRoots(1.0, 0, -1.0) print "Sau khi gọi hàm D=", D Chạy chương trình và phân tích kết quả.

$ python prog5.py Trước khi gọi hàm D = test Trong hàm D = 4. x1 = 1. x2 = -1. Sau khi gọi hàm D = test Vì vậy, sau khi xác định hàm printRoots(), chúng ta đã gán giá trị "test" cho biến D và kiểm tra kết quả: chuỗi "test" đã được in. Sau đó, họ gọi hàm printRoots(), trong thân hàm này, sau khi gán kết quả tính công thức phân biệt cho biến D, giá trị của biến D cũng được hiển thị: 4.0. Sau khi hàm hoàn thành, chúng ta in lại giá trị của biến D: lần này giá trị được gán lại bằng chuỗi "test".

Trên thực tế, D trong chương trình chính và D trong nội dung hàm printRoots() là hai biến khác nhau. Bạn có thể kiểm tra điều này bằng cách sửa đổi một chút chương trình của chúng tôi.

Hãy sử dụng hàm id(). Nó trả về địa chỉ của một đối tượng trong bộ nhớ. Chương trình được sửa đổi sẽ trông giống như thế này:

def printRoots(a, b, c):

D = b**2 - 4 * a * c import math print "Trong hàm D = ", D, "\nAdress:", id(D), "\n" x1 = (-b + math.sqrt(D )) / 2 * a x2 = (-b - math.sqrt(D)) / 2 * a print "x1 =", x1, "\nx2 =", x D = "test" print "Trước khi gọi hàm D = ", D, "\nAdress:", id(D), "\n" printRoots(1.0, 0, -1.0) print "Sau khi gọi hàm D = ", D, "\nAdress:", id(D), “\n” Kết quả của chương trình sẽ như sau:

$ python prog5.py Trước khi gọi hàm D = test Địa chỉ: Bản sửa đổi: 170 Hàm Trong hàm D = 4. Địa chỉ: x1 = 1. x2 = -1. Sau khi gọi hàm D = test Địa chỉ: Trên máy tính của bạn, các địa chỉ có thể khác nhau, nhưng bạn có thể rút ra kết luận giống nhau: địa chỉ D trong chương trình chính và D trong nội dung của hàm printRoots() là khác nhau.

Q.E.D.

Bài tập. Các tham số của hàm có phải là biến cục bộ không?

h3.9. Luồng thực thi Như đã đề cập, với sự ra đời của các hàm (và thủ tục), các chương trình không còn tuyến tính, liên quan đến điều này, nảy sinh khái niệm về luồng thực thi - trình tự thực hiện các lệnh tạo nên chương trình.

Việc thực thi một chương trình viết bằng Python luôn bắt đầu bằng biểu thức đầu tiên và các biểu thức tiếp theo được thực thi lần lượt từ trên xuống dưới. Hơn nữa, các định nghĩa hàm không ảnh hưởng đến luồng thực thi dưới bất kỳ hình thức nào, bởi vì Phần thân của bất kỳ hàm nào sẽ không được thực thi cho đến khi hàm tương ứng được gọi.

Khi trình thông dịch, phân tích cú pháp mã nguồn, đến một lệnh gọi hàm, nó sau khi tính toán các giá trị của các đối số, bắt đầu thực thi phần thân của hàm được gọi và chỉ sau khi hoàn thành mới tiến hành phân tích cú pháp lệnh tiếp theo.

Mọi thứ khá đơn giản, mặc dù việc theo dõi luồng thực thi trong các chương trình phức tạp thường trở thành một nhiệm vụ không hề đơn giản, bởi vì trong phần thân của bất kỳ hàm nào, một hàm khác có thể được gọi, hàm này cũng có thể chứa các lệnh gọi hàm trong phần thân của nó, v.v.

Tuy nhiên, trình thông dịch Python ghi nhớ từng hàm được gọi từ đâu và sớm hay muộn, nếu không có ngoại lệ nào được đưa ra trong quá trình thực thi, nó sẽ quay trở lại lệnh gọi ban đầu để chuyển sang lệnh tiếp theo.

Vì vậy, hãy tưởng tượng rằng chúng ta có ba hàm: f1(), f2() và f3(). Hơn nữa, họ còn gọi nhau như thế này:

print "f1() bắt đầu" print "Xin chào thế giới!" in "f1() kết thúc" def f2():

in "f2() bắt đầu" f1() Bản sửa đổi: 170 Hàm in "f2() kết thúc" def f3():

print "f3() bắt đầu" f2() print "f3() kết thúc" print "Chương trình chính bắt đầu" f3() print "Chương trình chính kết thúc" Để theo dõi trình tự các hoạt động, chúng tôi đã thêm các lệnh sẽ báo hiệu khi nó bắt đầu và mỗi chức năng kết thúc.

Vì vậy, hãy chạy chương trình và xem những gì chúng ta có:

$ python prog6.py Chương trình chính bắt đầu f3() bắt đầu f2() bắt đầu f1() bắt đầu Xin chào thế giới!

f1() kết thúc f2() kết thúc f3() kết thúc Chương trình chính kết thúc Hãy phân tích kết quả. Như đã đề cập, các định nghĩa hàm không ảnh hưởng đến việc thực thi chương trình chính dưới bất kỳ hình thức nào. Trường hợp ngoại lệ là khi trình thông dịch gặp lỗi cú pháp trong phần thân của hàm: ngay cả khi chưa đến lúc thực thi, nó sẽ in thông báo lỗi và thoát.

Chương trình chính bắt đầu bằng cách hiển thị thông báo về thời điểm bắt đầu của nó, sau đó hàm f3() được gọi, khi được trình bày sẽ gọi hàm f2(). Đến lượt nó, điều đó cũng thực hiện tương tự, gọi f1(). f1() cũng in thông báo về sự bắt đầu của nó, sau đó là lời chào thử nghiệm với thế giới và thông báo về việc hoàn thành. Luồng thực thi quay trở lại bên trong nội dung của hàm f2() tới điểm f1() được gọi, sau đó lệnh tiếp theo được thực thi, in ra một thông báo cho biết hàm f2() đã hoàn thành công việc của nó. Như bạn có thể đoán, luồng thực thi sẽ quay trở lại phần thân của hàm f3() và sau khi hoàn thành, quay trở lại chương trình chính.

h3.10. Sơ đồ ngăn xếp Để rõ ràng, bạn có thể vẽ cái gọi là sơ đồ ngăn xếp. Chúng được gọi như vậy là có lý do: chúng đại diện cho một ngăn xếp cuộc gọi.

Ngăn xếp là một cấu trúc dữ liệu đặc biệt giống như một chồng các tấm, vì việc tương tác với ngăn xếp được thực hiện theo quy tắc LIFO đặc biệt (Bản sửa đổi cuối cùng: 170 chức năng Ra - vào sau, ra trước). Quay trở lại sự tương tự với một chồng đĩa, chúng ta xếp các đĩa chồng lên nhau và nhặt chúng bắt đầu từ trên xuống. Phần sau chúng ta sẽ học cách lập mô hình ngăn xếp và một số cấu trúc dữ liệu khác thường được sử dụng để giải quyết Các nhiệm vụ khác nhau, nhưng hiện tại, hãy giới hạn bản thân ở mức hiểu biết trực quan về ngăn xếp, hãy vẽ sơ đồ ngăn xếp cho ví dụ từ phần trước.

F1() bắt đầu f1() kết thúc f1() Xin chào thế giới!

f2() bắt đầu f2() kết thúc f2() f3() bắt đầu f3() kết thúc f3() Chương trình chính bắt đầu Chương trình chính kết thúc chính Trong sơ đồ này, luồng thực thi được biểu thị bằng các mũi tên, chương trình con được biểu thị bằng các khối hình chữ nhật;

Các dòng đầu ra của chương trình được thêm vào bên phải và bên trái của sơ đồ ngăn xếp. Ở cuối ngăn xếp là chương trình chính (ký hiệu là chính);

Theo đó, nó không thể hoàn thành cho đến khi tất cả các chức năng nằm phía trên nó trong ngăn xếp cuộc gọi hoàn tất. Vì vậy, sử dụng ngăn xếp để theo dõi luồng thực thi là giải pháp đơn giản và tự nhiên nhất.

Trong quá trình thực hiện chương trình, ngăn xếp cuộc gọi có thể tăng lên và trống nhiều lần.

Khi một ngoại lệ xảy ra ở một trong các hàm, thường rất khó hiểu trong điều kiện nào (hoặc dưới tập hợp tham số nào) xảy ra lỗi, bởi vì Chức năng tương tự có thể được gọi từ nhiều nơi khác nhau trong chương trình. Do đó, để tạo điều kiện thuận lợi cho quá trình gỡ lỗi, trình thông dịch Python không chỉ hiển thị số dòng nơi xảy ra ngoại lệ mà còn hiển thị toàn bộ ngăn xếp cuộc gọi tại thời điểm ngoại lệ xảy ra.

Hãy điều chỉnh chương trình của chúng ta một chút để đưa ngoại lệ chia cho 0 vào hàm f1(), thay thế lời chào thành kết quả hòa bằng biểu thức a = 1/0:

print "f1() bắt đầu" a = 1/ print "f1() kết thúc"...

Bây giờ hãy chạy chương trình này:

$ python prog6.py Chương trình chính bắt đầu f3() bắt đầu f2() bắt đầu f1() bắt đầu Traceback (cuộc gọi gần đây nhất cuối cùng):

Bản sửa đổi: 170 Tệp Chức năng "prog6.py", dòng 17, ở định dạng ?

f3() Tệp "prog6.py", dòng 13, trong f f2() Tệp "prog6.py", dòng 8, trong f f1() Tệp "prog6.py", dòng 3, trong f a = 1/ ZeroDivisionError: chia số nguyên hoặc modulo cho 0 Sau thông báo về việc bắt đầu thực hiện hàm f1(), trình thông dịch đã hiển thị cái gọi là truy nguyên (các lập trình viên nói tiếng Nga thường nói truy nguyên hoặc đơn giản là theo dõi). Traceback không chỉ chứa tên của các hàm từ ngăn xếp cuộc gọi mà còn chứa số dòng mà mỗi cuộc gọi được thực hiện. Ngoài các con số, tên của tệp chương trình cũng được chỉ định vì dự án có thể chứa nhiều mô-đun. Vì vậy, việc tìm và sửa lỗi trở nên dễ dàng hơn nhiều.

h3.11. Hàm trả về kết quả Cuối cùng, chúng ta hãy làm quen với một tính năng quan trọng khác của hàm. Không khó để tưởng tượng một tình huống trong đó kết quả của một hàm có thể cần thiết cho hoạt động tiếp theo của chương trình. Nhưng sau khi hàm hoàn thành công việc của nó, tất cả các biến được khởi tạo trong phần thân của nó sẽ bị hủy, bởi vì họ là người địa phương.

Do đó, nếu cần trả kết quả của một hàm về chương trình con mà nó được gọi thì lệnh return sẽ được sử dụng để xử lý tiếp. Nó trông giống như thế này:

>>> def getSum(x,y):

Z = x + y... trả về z...

>>> print getSum(1,3) >>> Như bạn có thể thấy, giá trị được hàm trả về được trình thông dịch hiểu là kết quả của biểu thức gọi hàm này.

Trong Python, các hàm có khả năng trả về nhiều giá trị cùng một lúc7. Ví dụ: lấy hàm tính nghiệm của phương trình bậc hai:

>>> def PrintRoots(a, b, c):

D = b**2 - 4 * a * c... import math 7 Nhân tiện, trong Pascal và C++, không thể trả về nhiều giá trị từ một hàm cùng một lúc bằng các công cụ tiêu chuẩn. Đây là một tiện ích khác mà Python cung cấp.

Bản sửa đổi: 170 Hàm... x1 = (-b + math.sqrt(D)) / 2 * a... x2 = (-b - math.sqrt(D)) / 2 * a... return x1, x...

>>> print PrintRoots(1.0, 0, -1.0) (1.0, -1.0) Ngoài ra, chúng ta có thể gán kết quả của hàm cho nhiều biến cùng một lúc:

>>> x1, x2 = PrintRoots(1.0, 0, -1.0) >>> print "x1 =", x1, "\nx2 =", x x1 = 1. x2 = -1. >>> Rất có thể, bạn đã đoán được rằng các hàm dựng sẵn của Python trả về các giá trị theo cách giống hệt nhau.

Bản sửa đổi: 170 Đồ họa máy tính Chương 4. Đồ họa máy tính /* mô-đun rùa*/ Bản sửa đổi: 170 Biểu thức logic, điều kiện và đệ quy Chương 5. Biểu thức logic, điều kiện và đệ quy h5.1. Chú thích trong chương trình Bất kỳ kẻ ngốc nào cũng có thể viết một chương trình mà trình biên dịch sẽ hiểu được. Những lập trình viên giỏi viết chương trình mà những lập trình viên khác có thể hiểu được.

Martin Fowler, "Tái cấu trúc" Khi chương trình của bạn ngày càng lớn hơn, sớm hay muộn bạn cũng sẽ gặp phải một vấn đề: chúng sẽ trở nên khó đọc hơn. Lý tưởng nhất là chương trình phải được đọc dễ dàng như thể nó được viết bằng ngôn ngữ tự nhiên, nhưng một mặt, ngôn ngữ tự nhiên vẫn chưa có hình thức chính thức rõ ràng để mô tả các đối tượng và quy trình, mặt khác , việc hình thức hóa quá mức thường dẫn đến việc mô tả những điều đơn giản một cách phức tạp. Do đó, để cải thiện khả năng hiểu mã, việc chú thích mã bằng ngôn ngữ tự nhiên là rất hữu ích và hầu hết các ngôn ngữ lập trình, không ngoại trừ Python, đều cung cấp tính năng này.

Những người thích đùa nói rằng sau một ngày làm việc vất vả bên máy tính, một lập trình viên điển hình sẽ về nhà, ngồi xuống PC và do đó thư giãn. Nhưng sự thật còn tệ hơn nhiều so với trò đùa này: nhiều người trong chúng ta, khi đi làm về, dành thời gian còn lại trước khi đi ngủ... để lập trình bộ vi điều khiển. 🙂 Người bình thường không hiểu đâu, nhưng Arduino, Teensy hay ESP thực sự là một sở thích rất hay. Hạn chế duy nhất của chúng là cần phải lập trình ở mức khá thấp, nếu không phải trong Assembler thì là Arduino C hoặc Lua. Nhưng giờ đây Python đã xuất hiện trong danh sách ngôn ngữ dành cho vi điều khiển. Chính xác hơn là MicroPython. Trong bài viết này tôi sẽ cố gắng chứng minh khả năng của nó nhiều nhất có thể.

Tất cả đã bắt đầu từ đâu?

Tất cả bắt đầu với một chiến dịch Kickstarter. Damien George, một nhà phát triển đến từ Anh, đã thiết kế một bo mạch vi điều khiển dành riêng cho Python. Và chiến dịch đã diễn ra. Số tiền được công bố ban đầu là 15.000 bảng Anh, nhưng cuối cùng nó đã huy động được gấp sáu lần rưỡi số tiền đó - 97.803 bảng Anh.

Tại sao bảng này tốt hơn?

    Sức mạnh - MP mạnh hơn so với vi điều khiển Arduino, Bộ xử lý ARM 32-bit như STM32F405 (168 MHz Cortex-M4, bộ nhớ flash 1 MB, RAM 192 KB) được sử dụng ở đây.

    Dễ sử dụng - ngôn ngữ MicroPython dựa trên Python, nhưng được đơn giản hóa phần nào để các lệnh điều khiển cảm biến và động cơ có thể được viết chỉ bằng một vài dòng.

    Không có trình biên dịch - để chạy một chương trình trên nền tảng MicroPython, bạn không cần cài đặt phần mềm bổ sung trên máy tính. Bo mạch được PC phát hiện như một ổ USB thông thường - chỉ cần thả một tệp văn bản có mã vào đó và khởi động lại, chương trình sẽ ngay lập tức bắt đầu thực thi. Để thuận tiện, bạn vẫn có thể cài đặt trình mô phỏng thiết bị đầu cuối trên PC của mình, điều này giúp bạn có thể nhập trực tiếp các thành phần mã từ máy tính vào nền tảng. Nếu sử dụng nó, bạn thậm chí sẽ không phải khởi động lại bo mạch để kiểm tra chương trình, mỗi dòng sẽ được bộ vi điều khiển thực thi ngay lập tức.

    Chi phí thấp - so với Raspberry Pi, nền tảng PyBoard rẻ hơn một chút và do đó, dễ tiếp cận hơn.

  • Nền tảng mở - giống như Arduino, PyBoard là một nền tảng mở, tất cả các mạch sẽ được công khai, nghĩa là bạn có thể tự thiết kế và tạo một bảng như vậy tùy theo nhu cầu của mình.

Vậy thì sao, chỉ có phí chính thức thôi à?

KHÔNG. Với tất cả những ưu điểm của nó, PyBoard (đó là tên bảng mạch của nhà phát triển MicroPython) là một thú vui khá đắt giá. Nhưng nhờ nền tảng mở, nhiều bo mạch phổ biến đã có thể chạy MicroPython, được xây dựng riêng cho nó. Hiện nay có các phiên bản:

  • cho BBC micro:bit - Sự phát triển của Anh, được định vị là công cụ hỗ trợ giảng dạy chính thức cho các bài học về khoa học máy tính;
  • Circuit Playground Express là sự phát triển của công ty nổi tiếng Adafruit. Đây là một bảng bao gồm đèn LED, cảm biến, chân và nút. Theo mặc định, nó có thể được lập trình bằng Microsoft MakeCode cho Adafruit. Nó là một trình soạn thảo “mã” dựa trên khối (giống như Scratch);
  • ESP8266/ESP32 là một trong những bo mạch phổ biến nhất để phát triển IoT. Nó có thể được lập trình trong Arduino C và Lua. Hôm nay chúng tôi sẽ thử cài đặt MicroPython trên đó.

Chuẩn bị cho công việc

Trước khi viết chương trình, bạn cần cấu hình bo mạch, cài đặt chương trình cơ sở trên đó và cài đặt các chương trình cần thiết trên máy tính.

THÔNG TIN

Tất cả các ví dụ đã được kiểm tra và thử nghiệm trên các thiết bị sau:

  • Bảng NodeMCU ESP8266-12E;
  • Trình điều khiển động cơ L293D;
  • Màn hình I2C 0,96 inch 128 × 64;
  • Vòng NeoPixel của Adafbean 16.

Phần mềm điều khiển

Để flash firmware bo mạch, chúng ta sẽ cần Python. Chính xác hơn, thậm chí không phải chính anh ta mà là tiện ích Esptool, được phân phối bằng pip. Nếu bạn đã cài đặt Python (bất kể phiên bản nào), hãy mở một terminal (dòng lệnh) và gõ:

Pip cài đặt Esptool

Sau khi cài đặt Esptool, bạn cần làm hai việc. Điều đầu tiên là tải xuống phiên bản phần sụn cho ESP8266 từ trang web chính thức. Và thứ hai là xác định địa chỉ của bo mạch khi kết nối với máy tính. Cách dễ nhất là kết nối với máy tính của bạn, mở Arduino IDE và xem địa chỉ trong danh sách các cổng.

Để dễ hiểu hơn, địa chỉ board trong ví dụ sẽ là /dev/ttyUSB0, còn file firmware được đổi tên thành Esp8266.bin và nằm trên desktop.

Mở một thiết bị đầu cuối (dòng lệnh) và đi tới màn hình nền:

Máy tính để bàn CD

Định dạng bộ nhớ flash của bo mạch:

Esptool.py --port /dev/ttyUSB0 era_flash

Nếu xảy ra lỗi trong quá trình định dạng, thì bạn cần bật chế độ phần sụn theo cách thủ công. Chúng tôi nhấn nút đặt lại và đèn flash trên bảng. Sau đó, chúng tôi phát hành thiết lập lại và không phát hành flash, chúng tôi cố gắng định dạng lại.

Và tải firmware lên bo mạch:

Esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=phát hiện 0 Esp8266.bin

Tương tác với bảng

Tất cả sự tương tác với bảng có thể xảy ra theo nhiều cách:

  • qua cổng nối tiếp;
  • thông qua một trình thông dịch web.

Khi kết nối qua cổng Nối tiếp, người dùng sẽ thấy một trình thông dịch Python gần như bình thường trong thiết bị đầu cuối của mình (trong dòng lệnh).



Để kết nối qua Serial, có các chương trình khác nhau. Đối với Windows, bạn có thể sử dụng PuTTY hoặc TeraTerm. Đối với Linux - picocom hoặc minicom. Là một giải pháp đa nền tảng, bạn có thể sử dụng trình giám sát cổng Arduino IDE. Điều chính là xác định chính xác cổng và chỉ định tốc độ truyền dữ liệu là 115200.

Picocom /dev/ttyUSB0 -b115200

Ngoài ra, một số chương trình đã được tạo và đăng trên GitHub để hỗ trợ phát triển, chẳng hạn như EsPy. Ngoài cổng Nối tiếp, nó còn bao gồm trình chỉnh sửa tệp Python với tính năng tô sáng cú pháp cũng như trình quản lý tệp cho phép bạn tải xuống và tải tệp lên ESP.



Nhưng tất cả các phương pháp trên chỉ tốt khi chúng ta có cơ hội kết nối trực tiếp với thiết bị bằng cáp. Nhưng bo mạch có thể được tích hợp vào bất kỳ thiết bị nào và việc tháo rời nó chỉ để cập nhật chương trình là chưa tối ưu. Có lẽ, chính những trường hợp như vậy mà WebREPL đã được tạo ra. Đây là một cách để tương tác với bo mạch thông qua trình duyệt từ bất kỳ thiết bị nào nằm trên cùng một mạng cục bộ, nếu bo mạch không có IP tĩnh và từ bất kỳ máy tính nào, nếu có IP đó. Hãy thiết lập WebREPL. Để thực hiện việc này, hãy kết nối với bảng và quay số

Nhập webrepl_setup

Một thông báo xuất hiện về trạng thái tự động chạy của WebREPL và hỏi bạn nên bật hay tắt tính năng tự động chạy của nó.

Trạng thái tự động khởi động trình nền WebREPL: đã bật Bạn có muốn (E)nable hoặc (D)isable nó đang chạy khi khởi động không? (Dòng trống để thoát) >

Sau khi nhập q sẽ xuất hiện thông báo về việc đặt mật khẩu truy cập:

Để bật WebREPL, bạn phải đặt mật khẩu cho it Mật khẩu mới (4-9 ký tự):

Chúng tôi nhập nó và sau đó xác nhận. Bây giờ sau khi khởi động lại, chúng ta sẽ có thể kết nối với bo mạch thông qua Wi-Fi.

Vì chúng tôi chưa định cấu hình bo mạch để kết nối với mạng Wi-Fi nên nó hoạt động như một điểm truy cập. Tên của mạng Wi-Fi là MicroPython-******, trong đó tôi đã thay thế một phần địa chỉ MAC bằng dấu hoa thị. Chúng tôi kết nối với nó (mật khẩu - micropythoN).

  • Python,
  • Phát triển trang web
  • Nếu bạn đang tìm câu trả lời cho câu hỏi: “Nên chọn ngôn ngữ lập trình nào trước tiên”, thì trong khoảng 90% trường hợp, bạn sẽ được cung cấp Python - là ngôn ngữ dễ học nhất. Và hiển nhiên, một số lượng nhất định những người chưa học lập trình trước đây sẽ chọn Python vì những gợi ý này. Và ở đây chúng ta có một vấn đề sẽ được thảo luận dưới đây. Tất nhiên, kèm theo mô tả về cách tôi đến với cuộc sống này.

    Về tôi

    Ngay trong những năm sinh viên, tôi đã nhận ra rằng chuyên ngành của mình không hề màu hồng như năm 18 tuổi. Vì vậy, tôi bắt đầu nghĩ cách kiếm đủ tiền. Và sau khi nghe câu chuyện hồi đó ở 1C anh họ tôi nhận được số tiền điên cuồng như thế nào, tôi cũng quyết định gắn cuộc đời mình với IT.

    Ban đầu, đây là những trang web mẫu sử dụng công cụ xây dựng trang web và WordPress, sau đó tôi tham gia vào lĩnh vực SEO, và có lúc tôi tình cờ gặp Habr, sau đó tôi quyết định trở thành một lập trình viên chính thức. Tôi không có trình độ toán cao hơn nên tôi quyết định chọn một lĩnh vực không bắt buộc - phát triển web.

    Tôi có một câu hỏi rõ ràng: nên chọn ngôn ngữ nào - php/python/Ruby. Sau khi xem đủ bài viết về Habré, tôi thấy một số người ghét php sau khi xem một vài video tạo động lực từ Yandex. Tôi đã chọn Python. Tôi hy vọng bạn biết lợi ích của ngôn ngữ nên tôi sẽ không nói về nó.

    Đào tạo ngôn ngữ tiểu học

    Tôi kết hợp việc học ngôn ngữ với công việc chính của mình nên tôi đọc sách, xem các bài hướng dẫn và thực hiện các dự án nhỏ vào buổi tối. Nói chung, trong một năm tôi

    1) Sách đã học:

    • Mark Lutz - Học Python
    • Mark Lutz - Lập trình Python
    • Chad Fowler – Người cuồng lập trình
    • Bill Lubanovich - Python đơn giản
    2) Đã nghiên cứu rất nhiều video của các tác giả Ukraina/Tư sản trên Django
    3) Đã hoàn thành khóa học từ codeacademy
    4) Làm chủ PyCharm

    Dự án đầu tiên của bạn

    Sau đó, tôi nảy ra ý tưởng về một dịch vụ nhỏ về một chủ đề rất cụ thể mà tôi quyết định tạo ra để củng cố kiến ​​thức của mình về Python + Django.

    Khi tạo trang web, tôi

    1) Sách đã học:

    • John Duckett - HTML và CSS. Phát triển và thiết kế trang web
    • David Flanagan - JavaScript. Hướng dẫn chi tiết
    • Ben Forta - Tự học SQL.
    2) Tôi đã nghiên cứu tài liệu Django cho nhiệm vụ của mình
    3) Tôi đã nghiên cứu triển khai các dự án trên Django Gunicorn + nginx + centOS

    Dự án bình thường đầu tiên của tôi

    Sau khi trang web đầy đủ đầu tiên thất bại, tôi quyết định tạo ra thứ gì đó đáng giá, chọn ý tưởng, chọn phương án triển khai và hoàn thành nó vào buổi tối trong 3 tháng.

    Dự án đã cho thấy khả năng tồn tại của nó (cho đến ngày nay nó mang lại cho tôi một số tiền, điều mà tôi vô cùng hạnh phúc). Và tôi quyết định bơm nó lên tốt hơn.

    Sau khi đọc cuốn sách “Percival H. - Phát triển dựa trên thử nghiệm với Python”, tôi quyết định viết bài kiểm tra trước tiên dựa trên các thành phần Django, sau đó tra cứu tài liệu Selenium và đã thực hiện các bài kiểm tra bên ngoài.

    Tôi muốn được ngầu

    Sau khi mở các vị trí tuyển dụng cho các nhà phát triển Python-Django, tôi đã xem xét những gì khác thường được yêu cầu ở những vị trí tuyển dụng như vậy:
    • Khung phần còn lại của Django
    • Rau cần tây
    • Lốc xoáy/xoắn/asyncio (Chọn một)
    • Chế độ xem dựa trên lớp Django
    • Góc/Phản ứng (Chọn một)
    Đã dành 3 tháng để tìm hiểu/thử những điều này. Tôi cũng đã chọn thư viện chuẩn Python + thư viện phân tích cú pháp bên ngoài beautifulSoup.

    Bạn không thể làm việc nếu không có C/C++

    Có ý kiến ​​cho rằng nếu không có kiến ​​thức về C/C++ thì một lập trình viên không thể tự gọi mình là lập trình viên. Vì vậy, khi có thời gian rảnh tôi đã làm quen với các cuốn sách:
    • Brian Kernighan - Ngôn ngữ lập trình C
    • Stanley B Lippman – Ngôn ngữ lập trình C++. Khóa học cơ bản
    Tôi đọc sách, mày mò mã, xem phần biên dịch, xem các ví dụ về mã. Nói chung, bây giờ tôi không chú ý đến việc đề cập đến tài liệu tham khảo, con trỏ, sắp xếp, OOP và một loạt các mảng khác nhau với ở tốc độ khác nhau xử lý một phần tử tùy thuộc vào vị trí của nó.

    Tôi đã sẵn sàng chiến đấu!

    Và ở đây chúng ta đến điểm quan trọng nhất. Đã dành tổng cộng 2 năm để học tất cả các yếu tố của lập trình web mà tôi đã đề cập ở trên. Tôi cho rằng mình đã đủ sẵn sàng để ứng tuyển vào vị trí nhà phát triển web Python. Tất nhiên, tôi không biết rõ một số thứ, một số thứ thì hời hợt và một số thứ tôi không biết chút nào (ví dụ như Flask), nhưng hiểu biết chung và kỹ năng khá tốt.

    Và ở đây các vấn đề với Python bắt đầu mà mọi người thường không tập trung vào. Cụ thể là theo nhu cầu kinh doanh đối với các nhà phát triển Python cấp cơ sở/tiền trung cấp.

    Tôi bước vào thị trường với câu hỏi này.

    Mặc dù thoạt nhìn có vẻ như có khá nhiều vị trí tuyển dụng trong Python nhưng khi bắt đầu đi vào chi tiết cụ thể, mọi thứ sẽ thay đổi đáng kể.

    1. Ngay lập tức có một cuộc sàng lọc lớn các vị trí tuyển dụng trong đó Python chỉ là ngôn ngữ phụ trợ. Thông thường đây là các vị trí của nhà phát triển Java, Quản trị viên hệ thống, Tự động hóa QA. Ngoài ra, hiện có một lượng lớn học sinh bỏ học trong môn Học dữ liệu, vốn yêu cầu trình độ toán + ngôn ngữ R. Chỉ với Python bạn sẽ không thể tìm được vị trí tuyển dụng này.

    2. Hóa ra là ở thành phố của tôi không có chỗ trống nào cho Python, theo nghĩa đen là không có chỗ nào cả. Mở rộng tìm kiếm ra toàn khu vực, tôi cũng nhận được kết quả không như ý. Một số vị trí tuyển dụng về PHP, trong đó Python là một điểm cộng. Khi tôi mở bộ lọc trong 3 năm qua, tôi cũng phát hiện ra rằng không có vị trí tuyển dụng nào cho Python cả. Những thứ kia. các doanh nghiệp ở tỉnh thường lựa chọn những công nghệ đơn giản và phổ biến hơn Python.

    3. Sau khi mở các vị trí tuyển dụng Python trên một công cụ tìm kiếm tổng hợp, tôi phát hiện ra các xu hướng sau:

    • Hơn 90% vị trí tuyển dụng được đặt tại Moscow hoặc St. Petersburg
    • Hơn 90% vị trí tuyển dụng yêu cầu trình độ trung cấp trở lên / cấp cao
    • ~100% vị trí tuyển dụng cho các vị trí cấp dưới ở Moscow hoặc St. Petersburg (thường là từ những người khổng lồ)
    Nói cách khác, tình hình hóa ra là nếu bạn không sống ở Moscow, St. Petersburg và không đi “chinh phục” họ, thì thực tế bạn không có nơi nào để có được công việc đầu tiên.

    Tất nhiên, có một số nơi Python vẫn được sử dụng, chẳng hạn như ở Kazan. Nhưng thông thường đây là một công ty, nơi các vị trí tuyển dụng cũng rất trung cấp + / cao cấp.

    4. Lựa chọn tìm kiếm công việc từ xa ở cấp độ hiện tại cũng cho thấy người sử dụng lao động chưa sẵn sàng chấp nhận rủi ro như vậy. Ít kinh nghiệm + làm việc từ xa = đây là một kiểu tưởng tượng.
    Tuy nhiên, tôi vẫn có thể tìm ra một số lựa chọn, nhưng trong cuộc phỏng vấn đầu tiên, tôi thấy rõ rằng điều này thật vô nghĩa như: “Bạn làm việc cho chúng tôi trong ba tháng và nếu khách hàng trả tiền cho công việc của bạn, chúng tôi sẽ trả tiền cho bạn. cũng vậy." Không phải là lựa chọn tốt nhất

    5. Tôi đã nói chuyện với một số nhân sự của các công ty lớn, họ bày tỏ xu hướng này. “Chúng tôi thường thuê những người có ít nhất một năm kinh nghiệm về Python, cộng với kinh nghiệm về ngôn ngữ khác (hơn 3 năm). Thường xuyên nhất là php/Java." Nói cách khác, họ không hề cân nhắc việc thuê một người chỉ có Python.

    6. Sau khi trao đổi với các anh trên diễn đàn chuyên ngành thì thấy rõ đây là một tình huống khá điển hình. Từ câu chuyện của họ, rõ ràng là mọi người, sau khi tìm kiếm vô ích, đã bắt đầu làm việc trên PHP/1c hoặc bằng cách nào đó đã vượt qua quá trình tự động hóa công việc/dự án/thử nghiệm của riêng mình.
    Nhưng một lần nữa, tùy từng trường hợp.

    Nhìn chung, hóa ra Python là một ngôn ngữ tuyệt vời cho phép bạn tạo các dự án mạnh mẽ. Và điều ngẫu nhiên là sự tập trung của họ lại tập trung ở các thủ đô. Và vì đây là những dự án phức tạp nên cần có nhân viên ở cấp trung cấp trở lên. Một người mới học Python có sẵn sàng nhận một vị trí tuyển dụng như vậy không? Khó!

    Nhưng có một cách khác!

    Hiện tại, chỉ riêng trong thành phố của tôi đã có 24 vị trí tuyển dụng cho PHP ở nhiều cấp độ khác nhau (từ các công ty nhỏ cần duy trì trang web hiện tại cho đến những gã khổng lồ thương mại điện tử cung cấp khả năng mở rộng chức năng nhất quán). Và có cùng số lượng vị trí tuyển dụng cho 1C. Và trong khoảng một nửa số vị trí tuyển dụng này, họ sẵn sàng thuê một người ít nhất biết điều gì đó về lập trình. Rất có thể, đây không phải là nhiều nhất địa điểm tốt nhất, nhưng đây đã là công việc đầu tiên mà sau đó bạn sẽ chính thức trở thành một lập trình viên nhân sự có kinh nghiệm.

    Cuối cùng

    Hóa ra là bạn có thể học ngôn ngữ lập trình tuyệt vời Python và đi lại trên đường phố. Hoặc bạn có thể học php/1c “bị ghét” và kiếm việc làm. Tất nhiên, chất lượng của công việc này để lại nhiều câu hỏi - nhưng đây đã là kinh nghiệm.

    Đối với tôi, trong điều kiện của tôi (không đến Moscow/St. Petersburg), tôi thực sự đã dành thời gian học một ngôn ngữ hiện đang được yêu cầu riêng trong các dự án của riêng tôi. Tôi không thể tìm được việc làm tại địa phương hoặc từ xa. Bây giờ tôi đang chuyển sang php, vì đơn giản là nó hoạt động được.

    Do đó, nếu bạn không sống ở Moscow, St. Petersburg hoặc không phải là sinh viên của một trường đại học kỹ thuật, thì tôi sẽ không khuyên bạn học Python như ngôn ngữ đầu tiên của mình. Hãy chú ý đến PHP - luôn có chỗ cho nó, có công việc, có kinh nghiệm. Và con đường phát triển xa hơn đã là của bạn.

    tái bút Như bạn tôi đã nói với tôi, tình hình gần như tương tự ở Ruby. Nhưng ở đây tôi không còn có thể nói chuyện một cách tự tin nữa.