Skip to main content

Sử dụng community connector để lấy dữ liệu từ trực tiếp server của riêng bạn

Hôm nay thứ bảy đẹp trời, ngồi lục lại đống dữ liệu cũ từ năm 2017 về Facebook và GA lấy từ MeasureSchool bằng file excel. Lúc đó thì cũng lò mò làm cái Dashboard Report dữ liệu bằng Google Data Studio (GDS) nhưng là cho Report connect trực tiếp cái file source excel (Google Sheet) được bỏ lên Google Drive. Hôm nay, tui sẽ chia sẽ cái Community Connector mới làm để demo cách kết nối và đẩy dữ liệu từ Server của bạn (cụ thể ở đây là của tui) lên Google Data Studio. Read More

Tạo module Backend, Frontend và Api với Laravel 5.7 (version 2)

Hôm nay có thời gian rãnh rỗi. Tui viết lại bài tạo module version 2 để cập nhật lại cho bài lần trước, về cơ bản thì cũng không khác gì, nhưng có một số thay đổi khi load route và views cho từng module. Bài này tui dùng Laravel 5.7 nhé, và coi như các bạn đã cài WAMP Server rồi nhé.

1. Tạo project:

Hôm nay là ngày 01/12, cho nên tui chọn tên project là hestia nhé. Giả sử, thư mục WEB_ROOT cho project này hiện lại là E:\Server\www\learning:

Chờ đến khi nó chạy xong như hình sau:

Khi đó trong thư mục hestia, chúng ta sẽ có cây thư mục như sau:

Để đơn giản, tui không tạo virtual host để trỏ vào thư mục hestia/public mà tui sẽ dùng cái Web Server có sẵn của laravel để run cái project này luôn. Chuyển vào thư mục hestia, run command sau:

Mở Chrome hay FireFox lên, chạy http://localhost:9000/, nếu nó hiện ra cái trang Laravel to đùng thì ổn.

Nếu các bạn bỏ tham số –port=9000 thì mặc định Web Server nó sẽ listen ở port 8000 nha.

2. Tạo module Backend, Frontend và Api:

Tại thư mục app, các bạn tạo thư mục Modules và các thư mục con tương ứng như sau:

Chú ý: trong thự mục Modules/Api, không có thư mục Views nha, lý do là Api không cần render views.

Tại thư mục config, các bạn tạo một file tên là modules.php:

Với nội dung như sau:

Mục đích của việc tạo file modules.php để đễ dàng quản lý việc load routes cũng như views theo từng module tương ứng. Tiếp theo, các bạn tạo một Service Provider để nó kiểm tra và load module tương ứng. Tại thư mục app/Modules, các bạn tạo một file tên là ModuleServiceProvider.php:

Với nội dung sau (hơi bị dài nha):

Thực chất là tui sẽ dùng cái ModuleServiceProvider.php này để thay thế cho cái file Provider/RouteServiceProvider.php mặc định của Laravel.

Đối với hàm mapApi(), do tui muốn là có nhiều file route tương ứng với từng version cho api, kiểu như là:

  • v1.route.php, tương ứng với api/v1/*
  • v2.route.php, tương ứng với api/v2/*

Cho nên sẽ có phần scandir cho thư mục Api/Routes để lấy cái version name cho từng route.

Edit file config/app.php để load cái Modules/ModuleServiceProvider.php và unload cái Provider/RouteServiceProvider.php. Mở file config/app.php, tìm đến cái array ‘providers’:

comment cái dòng App\Providers\RouteServiceProvider::class,

và thêm App\Modules\ModuleServiceProvider::class,

Để cho chắc chắn rằng Laravel 5 nó hiểu cái namespace App\Modules, chúng ta mở file composer.json, tìm đến mục psr-4 nằm trong mục autoload, thêm “App\\Modules”: “app/Modules” ngay bên dưới “App\\”: “app/”:

Để chắc ăn, các bạn nên stop Web Server (ấn Ctrl + C) và start lại nhé.

3. Tạo route cho từng module

Ở phần này, tui sẽ map route với Controller@action nhé.

3.1. Backend module:

Các bạn tạo các file như sau:

Nội dung các file tương ứng như sau:

Backend/Controllers/Controller.php:

Backend/Controllers/HomeController.php:

Backend/Routes/web.php:

Backend/Views/home/welcome.blade.php:

Kết quả:

3.2. Frontend Module:

Cũng tạo các file giống như Backend:

Nội dung thì y chang, chỉ khác cái namespace và nội dung message:

Frontend/Controllers/Controller.php:

Frontend/Controllers/HomeController.php:

Frontend/Routes/web.php:

Frontend/Views/home/welcome.blade.php:

Kết quả:

3.3. Api Module:

Tạo các file sau:

Nội dung các file như sau:

Api/Controllers/Controller.php:

Api/Controllers/V1Controller.php:

Api/Routes/v1.route.php:

Kết quả trên Postman:

 

Vậy là xong roài đó. Hy vọng giúp ích được cho các bạn.  THANK-YOU

Monitor việc gọi API real-time với Go và Redis

Hôm trước, tui có một bài viết về việc sử dụng cơ chế Pub/Sub của Redis bằng command line. Hôm nay tui sẽ dùng Golang kết hợp với Redis để làm một cái demo nho nhỏ để đẩy message qua lại giữa Weather Services với API Monitor Server, sau đó dùng socket để broadcast message này ra web.

1. Mô tả bài toán:

Khỏi nói nhiều, các bạn xem hình sẽ hiểu:

Dùng Postman để gọi endpoint API (như trong bài Concurrency trong Golang) “http://localhost:9000/api/temperature/city_name”. Thì chương trình “Weather Services” sẽ xử lý việc tính nhiệt độ, sau đó trả dữ liệu về cho user đồng thời sẽ PUBLISH một message dạng json vào Redis thông qua một channel.

Tiếp, một chương trình khác là “API Monitor” sẽ SUBSCRIBE channel này để nhận message json, sau đó sẽ dùng socket để broadcast message này đến các web client đang kết nối.

2. Viết code chương trình:

Weather Services:

Đối với chương trình này, chúng ta sẽ sử dụng lại code của bài trước và thêm phần connect với Redis:

Install Redis client:

$ go get -u “github.com/gomodule/redigo/redis”

tại file main.go:

import package: “github.com/gomodule/redigo/redis”

 

Tạo kiểu dữ liệu mới:

Thêm một hàm để publish message qua Redis:

Hàm publishMessage() sẽ nhận 2 tham số:

  • Redis Connection
  • Channel lưu giữ data cần publish

Ta sẽ cho hàm này chạy như là một routine.

Trong hàm main, ta thêm đoạn code để connect với Redis:

Trong hàm xử lý của api endpoint “/api/temperature/{city}”, thêm vào cuối hàm này đoạn code sau:

Sửa hàm temperature để trả về 2 giá trị, 1 là nhiệt độ, 2 là success:

Thêm biến success khi gọi hàm temperature():

API Monitor:

Sử dụng iris để tạo Web Server:

install iris:

$ go get -u “github.com/kataras/iris”

install go-socket.io:

$ go get -u “github.com/googollee/go-socket.io”

file main.go:

import package:

Tạo hàm deliverMessage() để nhận message từ Redis và broadcast thông qua socket

Hàm này nhận 2 tham số:

  • Redis Connection
  • Socket Server

Tiếp, trong hàm main();

Tạo Web server và socket:

Connect đến Redis và tạo Pub/Sub connection để Subscribe message:

Mở socket:

Tạo routine:

Run Iris web server:

tạo một file index.html trong thư mục public, để làm web client (sử dụng jquery, socket.io client):

3. Chạy chương trình:

Run Redis server (Xem chi tiết các chạy Redis ở bài Redis Pub/Sub):

redisserver

Tại thư mục weather-services-redis:

$ go run main.go

Tại thư mục api-monitor:

$go run main.go

Mở Chrome và Firefox, nhập url http://localhost:8000

Dùng Postman để gọi API:

http://localhost:9000/api/temperature/tokyo

http://localhost:9000/api/temperature/seoul

http://localhost:9000/api/temperature/saigon

Khi đó, các bạn sẽ thấy kết quả json vừa trả về cho Postman và đồng thời Message cũng sẽ được notify trên Chrome và Firefox.

Kết quả như sau:

 

Source code:

https://github.com/lmdat/weather-services-redis

https://github.com/lmdat/api-monitor

 

Concurrency kết hợp với RESTful API trong Golang

Sau vài ngày “chìm đắm” trong mớ hỗn độn của ngôn ngữ Go để tìm hiểu về cái gọi là concurrency với 2 khái niệm mới đó là GoRoutine và Channel thì tui thấy rằng bạn Go này hay quá. Chưa bao giờ thấy việc lập trình concurreny nó dễ dàng như vậy. Sau khi “học” xong thì cảm thấy Go nó có một chút gì đó mạnh mẽ của C/C++, uyển chuyển của PHP/Python. Cú pháp thì gọn gàng (có thời gian, tui sẽ viết bài về cách học ngôn ngữ Go này).

Đó giờ tui làm backend chỉ dùng PHP là chính bao gồm viết website cũng như làm RESTful api. Cái hạn chế của PHP đó là PHP là scripting, có timeout khi run script. Cho nên khi build API hoặc là gọi API từ một service khác sẽ gặp một số rủi ro về việc blocking request trong trường hợp tạo nhiều request để gọi API cùng lúc. Có thể tại thời điểm này, PHP cũng đã có những giải pháp để giải quyết vấn đề trên. Nhưng hôm nay, tui muốn sử dụng Go để làm giải pháp cho vấn đề non-blocking request.

1. Goroutine và channel

Bài toán đặt ra là như thế này. Tui có một hệ thống cung cấp Rest API, khi gọi đến endpoint này, hệ thống sẽ phải collect dữ liệu từ nhiều nguồn khác từ các service khác thông qua Rest API luôn, sau đó tổng hợp dữ liệu này lại và trả kết quả về cho người dùng. Giả sử tui phải gọi API từ 15 service khác nhau, nếu bình thường, tui sẽ phải tạo 15 cái request và thực hiện tuần tự 15 cái request này. Nếu trung bình, 1 request xử lý xong trong vòng từ 0.5s – 1s thì 15 request tui mất khoản 7.5s – 15s (do vấn đề blocking request, xử lý xong request này mới đến request kế tiếp), điều này thật sự không thể chấp nhận đối với việc gọi API.

Nếu ta áp dụng Concurrency (nó hơi khác với Parallel nha) với 15 request này, có nghĩa là cho 15 request này được xử lý đồng thời thì tui chỉ mất từ 0.5s – 1s cho tất cả các request, vậy thì performance tăng lên rất nhiều.

Ví dụ cụ thể đi ha. Tui đã đăng ký 3 cái api để lấy nhiệt độ tại thời điểm request của một thành phố bất kỳ đó là:

(Chỉ tìm được 3 cái này nó free thôi, coi như là nhiều hơn 1 là được rồi, để minh họa bài toán trên cũng ok nha.)

Tạo 3 routine để xử lý đồng thời 3 cái request đến 3 cái api trên, dùng channel để hứng dữ liệu sau khi các routine này xử lý phần lấy giá trị nhiệt độ từ kết qua json trả về. Tiếp theo, tính trung bình nhiệt độ có được và trả kết quả trung bình này cho Rest API, sau đó Rest API này sẽ trả kết quả json về cho người dùng. Xem cái hình sau nhé:

2. Code chương trình bằng Go:

2.1. Tạo Interface:

Do ta có 3 service cần gọi, mỗi service này thì trả dữ liệu JSON về có cấu trúc khác nhau, nên ta cần tạo một interface chung có một hàm là GetTemperature, sau đó tạo 3 cái provider tương ứng với 3 service rồi implement cái interface này.

weatherapi/weather_interface.go

2.1. Tạo các provider:

Mỗi provider cụ thể sẽ có  fields: APIKey và URL:

weatherapi/open_weather_map.go

weatherapi/api_xu.go

weatherapi/weather_bit.go

2.3. Tạo hàm temperature() để collect và tính nhiệt độ trung bình:

Tạo một danh sách chứa các Provider:

Tạo kiểu dữ liệu TemperatureData để lưu dữ liệu là nhiệt độ (độ C, độ K, độ F) để trả về cho người dùng khi người dùng gọi Rest API

Hàm temperature, trong hàm này ta sẽ dùng goroutine và channel

2.4. Khởi tạo các provider:

Tạo các provider với APIKey và URL tương ứng, sau đó thêm chúng vào ProviderList:

2.5. Tạo Rest API với Gorilla Mux:

Tổng hợp lại trong file main.go:

3. Run chương trình:

Đứng ngay tại thư mục chứa file main.go, run lệnh:

$ go run main.go

Dùng PostMan để test Rest API:

http://localhost:9000/api/temperature/saigon

http://localhost:9000/api/temperature/tokyo

http://localhost:9000/api/temperature/paris

Kết quả hiển thị bên server:

Tui để source code tham khảo bài này tại git nhé: https://github.com/lmdat/weather-services

Cách viết của tui trong bài này thật sự chưa hoàn hảo đâu, sẽ có một vài bug xuất hiện đó, nhưng về cơ bản, hi vọng bài viết này sẽ giúp các bạn có hứng thú với ngôn ngữ Go hơn cũng như cách sử dụng goroutinechannel trong lập trình concurrency.

Function trong C#

Các bạn đã giải bài tập chưa, nếu chưa thì tập giải đi nha. Trong khi giải bài tập, có những bài các bạn sẽ viết code rất là dài trong hàm Main. Điều này cũng bình thường thôi, nhưng mà nó sẽ làm cho chúng ra rối mắt khi đọc lại code, hoặc khi người khác review code của các bạn viết cũng rất khó khăn, hoặc có một số đoạn code các bạn có thể dùng đi dùng lại ở một vài chổ trong chương, chẳng lẽ cứ phải viết lại (hoặc copy/paste xuống dưới). Để viết code cho gọn, các bạn sẽ tách các đoạn logic code ra thành từng hàm, sau đó gọi lại hàm đó ở nhưng nơi mà các bạn muốn. Hôm nay, tui sẽ giới thiệu về cách viết hàm như thế.

1. Khái niệm hàm:

Hàm là một khối các dòng lệnh được đặt tên, để thực thi một thao tác nào đó, sau đó trả về một kết quả mong muốn. Hàm được tạo khi ta có nhu cầu sử dụng lại một khối lệnh nào đó nhiều lần ở những nơi khác nhau trong chương trình.

Cấu trúc của một hàm như sau:

Ở đây, tạm thời các bạn hiểu từ khóa static là để chúng ta có thể gọi cái hàm này trong hàm Main của chương trình nhá. Sau này học hướng đối tượng thì các bạn sẽ tìm hiểu kỹ hơn.

Các bạn chú ý, lệnh return là lệnh dùng để kết thúc một hàm đồng thời trả giá trị ra khỏi hàm. Thông thường, return sẽ được đặt ở cuối hàm, nhưng cũng có trường hợp ta có thể đặt return ở bất kỳ nơi đâu trong thân hàm tùy theo hoàn cảnh cụ thể.

Nếu như hàm của các bạn không cần phải trả giá trị về thì các bạn viết như sau:

Các bạn thay return_type bằng từ khóa void (có nghĩa là không trả giá trị gì), không cần dùng lệnh return. Đa số trường hợp, các bạn sẽ không dùng lệnh return, nhưng trong trường hợp cần dùng lệnh return để thoát khỏi hàm thì các bạn viết là return null;

Còn một lưu ý nữa là các bạn không được viết hàm bên trong một hàm khác nha. Cái này các bạn mới học thường viết như vầy lắm nà:

Để sử dụng hàm, các bạn chỉ cần gọi tên hàm như sau:

2. Tham số của hàm:

Khi viết hàm, chúng ta sẽ có nhu cầu là truyền cái gì đó vào trong hàm, sau đó tính toán, làm đủ thứ trò trong thân hàm, sau đó trả giá trị ra ngoài hàm. Do đó, để truyền giá trị vào trong hàm, ta cần cái tham số (parameter) để nhận giá trị đầu vào này.

Các biến p1, p2, …pn được gọi là biến tham số của hàm.

Ta viết lại hàm Add() với 2 tham số là x, y để làm phép công 2 số bất kỳ:

Biến: a, b. Biểu thức: (a * 2), (b + 5). Số nguyên: 3, 15 được gọi là các đối số (Argument) của hàm Add()

3. Phân loại tham số trong C#:

Trong C#, chúng ta có tất cả 6 loại tham số:

  1. Value parameter
  2. Reference parameter
  3. Output parameter
  4. In parameter
  5. Optional parameter
  6. Parameter array

Đối với Parameter Array thì chúng ta sẽ học trong bài Array.

4. Cách truyền tham số:

4.1. Value Parameter:

Giá trị truyền vào trong hàm sẽ được copy ra từ đối số (đa số trường hợp chúng ta sẽ truyền theo kiểu này). Điều này có nghĩa là nếu trong thân hàm các bạn có thay đổi giá trị của tham số thì cũng không ảnh hưởng đến giá trị của đối số.

Ví dụ kinh điển: hàm Swap là hàm hoán đổi giá trị của hai số a = 5, b = 10 ==> mong muốn sau khi hoán đổi: a = 10, b = 5

Kết quả:

Before call method:

a=5,b=10

After call method:

a=5,b=10

trước và sau khi gọi hàm Swap, giá trị của a, b vẫn không đổi. Các bạn xem hình sau sẽ hiểu cơ chế:

a, b đã được copy giá trị ra một vùng nhớ khác (màu cam), khi đó x, y chỉ tham chiếu đến giá trị vùng nhớ màu cam thôi, khi thay đổi giá trị x, y trong thân hàm thì cũng chỉ thay đổi giá trị trên vùng nhớ màu cam thôi. Cho nên cuối cùng giá trị của a,b ở vùng nhớ màu xanh không thay đổi. Đó là các truyền tham trị (value parameter)

4.2. Reference parameter:

Để thay đổi được giá trị của a, b sau khi gọi hàm Swap, ta dùng kiểu tham chiếu như sau, ta thêm từ khóa ref vào trước tham số và đối số khi muốn thay đổi giá trị.

Các biến truyền theo kiểu ref phải được khởi tạo giá trị trước khi truyền, và trong thân hàm ta có thể không thay đổi giá trị của nó cũng được

Kết quả:

Before call method:

a=5,b=10

After call method:

a=10,b=5

Sau khi gọi hàm Swap, thì giá trị của a, b đã thay đổi. Xem hình sau để hiểu cơ chế:

Do ta dùng từ khóa ref, cho nên lúc này a và x đều tham chiếu đến cùng một vùng nhớ do đó khi thay đổi giá trị của x thì a cũng thay đổi luôn (tương tự cho b và y).

4.3. Output parameter:

Thằng này thì dùng từ khóa out cho tham số và đối số. Nó cũng giống như truyền theo kiểu ref, giá trị của biến sẽ thay đổi sau khi gọi hàm.

Chú ý là nó khác kiểu ref ở điểm sau: có thể không cần khởi tạo giá trị trước khi truyền vào hàm, nhưng trong thân hàm bắt buộc phải thay đổi hoặc gán giá trị mới cho nó.

Kết quả:

Before call method:

a=0

After call method:

a=15

4.4. In parameter:

Cái loại này cũng ít dùng, nhưng tui cũng nói sơ qua cho các bạn biết. Truyền biến kiểu này thì dùng từ khóa in ở trước tham số và đối số, kiểu truyền biến của nó cũng giống như ref nhưng có điều là ta không thể thay đổi giá trị của nó trong thân hàm. Dùng kiểu này khi ta muốn chắc chắn rằng biến ta truyền vào có thể được dùng nhưng không thể được thay đổi.

4.5 Optional parameter:

Optional parameter là tham số cho phép ta đặt cho tham số một giá trị mặc định, có nghĩa là nếu ta không truyền đối số cho nó thì nó sẽ lấy giá trị mặc định đó để sử dụng.

Kết quả:

Name: Peter, Age: 18

Name: Mike, Age: 18

Name: Sarah, Age: 24

Chú ý: khi muốn truyền đối số cho hàm mà không theo thứ tự của tham số, các bạn viết như sau: tham_số: đối_số

Tóm lại, đối với tham số của hàm, thì 3 kiểu value, ref, out thì được dùng nhiều.

Bài tập cho các bạn, các bạn viết lại các bài tập ở bài trước bằng cách tạo hàm và gọi nó trong hàm Main nhé.

 

Bài 10: Tính tổng của n số nguyên dương đầu tiên

Bài 10:  Nhập số n > 0. Tính S(n) = 1 + 2 + 3 + … + n.

Solution:

Cho vòng lặp for chạy từ 1 -> n, ta cộng dồn từng số vào một biến sum

Run code online: https://repl.it/@lmdat/bai-10

Bài 05: Nhập một tháng có giá trị từ 1 – 12. Cho biết tháng đó thuộc quý mấy

Bài 05: Nhập một tháng có giá trị từ 1 – 12. Cho biết tháng đó thuộc quý mấy

Solution:

1. Kiểm tra tháng nhập vào phải là số > 0 và < 13

2. Kiểm tra xem tháng nhập vào thuộc đoạn nào:

1-3: quý I

4.6: quý II

7-9: quý III

10-12: quý IV

Run code online: https://repl.it/@lmdat/bai-05

Bài 02: Nhập 2 số thực x, y. Kiểm tra xem chúng cùng dấu hay trái dấu

Bài 02: Nhập 2 số thực x, y. Kiểm tra xem chúng cùng dấu hay trái dấu

Solution:

1. Kiểm tra tích của x và y, nếu > 0 thì cùng dấu, nhỏ hơn 0 thì trái dấu

2. Nếu x và y đều = 0 hoặc x = 0 hay y = 0 thì thông báo là không xác định

Run code online: https://repl.it/@lmdat/bai-02

bài 01: Viết chương trình tìm số lớn nhất giữa 3 số thực x, y, z

Bài 01:  Viết chương trình tìm số lớn nhất giữa 3 số thực x, y, z

Solution:

1. Tìm số lớn hơn giữa 2 số x và y, tạm gọi là max.

2. Sau đó tìm giá trị lớn hơn giữa max và z.

Chú ý: Các bạn có thể dùng hàm Math.max() để lấy giá trị lớn nhất giữa 2 số. Nhưng trong bài thì tui không sử dụng mà làm theo cái solution trên.

Run code online: https://repl.it/@lmdat/bai-01

Câu lệnh điều khiển trong C#

Đặt một câu hỏi như thế này nhé. Nếu có sẳn chương trình “Giải Phương trình Bậc 2”, vậy ta có thể giải luôn “Phương Trình Bặc 1” trong đây luôn được không? Hay muốn in ra màn hình 1000 lần câu “I Love You” mà không cần phải viết 1000 lần cầu lệnh in màn hình không? Câu trả lời là có, và câu lệnh điều khiển sẽ giúp các bạn.

Vậy câu lênh điều khiển là gì? Đơn giản, câu lệnh điều khiển là các câu lệnh giúp lập trình viên “bẻ lái” chương trình của mình sao cho thích hợp với các giá trị của dữ liệu đầu vào hoặc giá trị dữ liệu phát sinh trong quá trình một chương trình nó đang chạy. C# cho chúng ta các loại câu lệnh điều khiển như sau:

  • Câu lệnh rẽ nhánh – If
  • Câu lệnh lựa chọn – switch … case
  • Câu lệnh vòng lặp
  • Câu lệnh break và continue

1. Câu lệnh rẽ nhánh – if:

Trong câu lệnh rẽ nhánh, ta có các loại như sau:

if

Nếu điền kiện trả về (sử dụng toán tử logic) là:

true: chương trình sẽ thực hiện các lệnh trong khối ngoặc { }

false: bỏ qua, không thực hiện.

Chú ý: Nếu trong khối lệnh if chỉ có một câu lệnh thì ta không cần dấu ngoặc { } (như dòng 2, 3 trong ví dụ trên)

if … else

Khác với khối if, true thì thực hiện, false thì bỏ qua. Thì với if … else nếu điền kiện logic là:

true: thực hiện các lệnh trong đấu ngoặc { } của if, cụ thể là Statement-1

false: thực hiện các lệnh trong đấu ngoặc { } của else, cụ thể là Statement-2

if … else if [… else if] … else

Nếu chúng ta có nhiều hơn 2 lựa chọn thì sử dụng khối lệnh if … else if [… else if] … else

Tới đây thì đã có bài tập cho các bạn làm rồi đấy  Overjoy

 

2. Câu lệnh lựa chọn switch … case:

 

Cách dùng switch … case cũng giống như if … else if [… else if] … else nhưng khác một điểm là: các bạn để ý nhé, cứ mỗi một value của từng case mà thỏa cái expression của switch thì nó thực hiện các lệnh bên trong nó và cuối cùng phải có lệnh break để kết thúc cái case đó và thoát ra khối lệnh switch … case.

Nếu như không có lệnh break thì nó sẽ nhảy xuống trường hợp kế tiếp để thực hiện. Nếu không có value nào thỏa expression thì nó nhảy vào default luôn sau đó mới thoát khối lệnh switch … case

 

3. Câu lệnh vòng lặp

Chúng ta thường sử dụng các vòng lặp sau: for, while, do … while

for:

Nếu condition còn là true thì Statement sẽ còn được thực hiện. Vòng lặp sẽ dừng nếu Condition là false hoặc dùng lệnh break;

Đơn giản

Với đoạn code trên thì:

Initializer là int i = 0; Condition là i < 10; IterationExpr là i++. Theo như hình vẽ thì:

  1. Đầu tiên vòng lặp for sẽ kiểm tra xem i có nhỏ hơn 10 hay không, lúc này i=0 nhỏ hơn 1000.
  2. Tiếp theo là nó sẽ thực hiện câu lệnh Console.Writeline(“I Love You”);
  3. Sau đó nó sẽ tăng giá trị i lên 1 bằng lệnh i++, rồi quay lên bước 1 để kiểm tra i tiếp và cứ như thế cho đến khi i có giá trị là 1000 thì lúc này điều kiện i < 1000 là false, khi đó vòng lặp for kết thúc.

Cho đếp phức tạp:

lồng if trong for:

lồng switch … case trong for:

while:

  • Trong khi condition còn là true thì Statement được thực hiện. Nếu condition là false hoặc gặp câu lệnh break; thì dừng và thoát khỏi vòng lặp.
  • Đối với vòng lặp while thì nó kiểm tra condition trước khi thực hiện.

Condition là z > 0. Nếu i vẫn còn lớn hơn 0 thì thực hiện vòng lặp.

Đoạn code trên thực hiện như sau:

  1. Đầu tiên z có giá trị là 5, kế tiếp vòng lặp while sẽ kiểm tra xem z có lớn hơn 0 hay không, lúc này z=5 lớn hơn 0.
  2. Thực hiện lệnh Console.WriteLine(z); Sau đó thực hiện lệnh z -= 1 để giảm giá trị z xuống còn 4.
  3. Tiếp tục quay lên bước 1 kiểm tra tiếp z có lớn hơn 0 hay không cho đến khi lệnh z -= 1 giảm giá trị xuống còn 0 thì lúc này condition z > 0 là false, khi đó vòng lặp while dừng lại và giá trị z in ra mằn hình là từ 5 4 3 2 1.

Một ví vụ khác, Secret Number:

do … while:

 

  • Thực hiện Statement trong khi Condition là true. Nếu condition là false hoặc gặp lệnh break; thì dừng.
  • do … while thì ngược với while là nó thực hiện Statement ít nhất 1 lần rồi mới kiểm tra condition.
  • Các bạn chú ý cái dấu ; màu đỏ sau đóng ngoặc của condition nhé, không có là nó báo lỗi đấy.

Condition là k < 10.

Đoạn code này nó chạy như vậy nè các bạn:

  1. Đầu tiên nó thực hiện câu lệnh Console.WriteLine(k++); và đồng thời tăng giá tri k thêm 1 bằng lệnh k++.
  2. Rồi sau đó nó mới kiểm tra k xem có nhỏ hơn 10 hay không, lúc này k=1 vẫn nhỏ hơn 10.
  3. Tiếp tục quay lên bước 1 thực hiện câu lệnh Console.WriteLine(k++); và lại tăng k thêm 1 cho đến khi k có giá trị là 10 thì vòng lặp dừng.

Viết lại ví dụ Secret Number:

4. Break và Continue:

  • Break: dùng để thoát khỏi vòng lặp hoặc kết thúc một case của switch.
  • Continue: dùng để bỏ qua những dòng lệnh sau nó và tiếp tục vòng lặp.

Break:

Continue:

Để tiện cho việc viết code, tui giới thiệu các bạn một số hàm tính toán và hàm nhập xuất console:

Nhập xuất màn hình:

Sử dụng lớp Console trong namespace System

Console.Write() In một chuỗi ra màn hình
Console.WriteLine() In một chuỗi ra màn hình, kết thúc chuỗi là ký tự xuống dòng
Console.Read() Đọc một ký tự được nhập từ bàn phím
Console.ReadLine() Đọc một chuỗi ký tự được nhập từ bàn phím

 

Để Convert các giá trị nhập vào từ bàn phím. Chúng ta dùng lớp Convert:

Convert.ToInt16() Convert.ToDouble()
Convert.ToInt32() Convert.ToBoolean()
Convert.ToInt64() Convert.ToString()
Convert.ToFloat() Convert.ToChar()

 

Tính toán:

Sử dụng lớp Math cũng trong namespace System:

Math.Abs(x) Lấy trị tuyệt đối của x
Math.Max(x, y) Trả về giá trị lớn hơn
Math.Min(x, y) Trả về giá trị nhỏ hơn
Math.Sqrt(x) Lấy căn bậc 2 của x
Math.Pow(x, n) Lũy thừa bậc n của x
Math.Round() Làm tròn số
Math.Floor(x) Làm tròn dưới
Math.Ceiling(x) Làm tròn trên

BÀI TẬP:

Bài 01: Viết chương trình tìm số lớn nhất giữa 3 số thực x, y, z được nhập từ bàn phím.

Bài 02: Nhập 2 số thực x, y. Kiểm tra xem chúng cùng dấu hay trái dấu.

Bài 03: Giải phương trình bậc 1 ax + b = 0 với a, b là các số thực được nhập từ bàn phím.

Bài 04: Giải phương trình bậc 2 ax2 + bx + c = 0 với a, b, c là các số thực được nhập từ bàn phím. Xét luôn cả trường hợp phương trình bậc 1.

Bài 05: Nhập một tháng có giá trị từ 1 – 12. Cho biết tháng đó thuộc quý mấy.

Bài 06: Viết chương trình nhập ngày, tháng, năm. In ra màn hình ngày kế tiếp (ngày, tháng, năm)

Bài 07: Viết chương trình nhập ngày, tháng, năm. In ra màn hình ngày trước đó (ngày, tháng, năm)

Bài 08: Viết chương trình nhập ngày, tháng, năm. Tính xem ngày đó là ngày thứ bao nhiêu trong năm.

Bài 09: Nhập vào một số nguyên có giá trị từ 10 – 99999. In ra màn hình cách đọc số này.

Bài 10: Nhập số n > 0. Tính S(n) = 1 + 2 + 3 + … + n.

Bài 11: Nhập số n > 0. Tính S(n) = 12 + 22 + 32 + … + n2.

Bài 12: Nhập số n > 0. Tính S(n) = 1 + 1/2 + 1/3 + … + 1/n.

Bài 13: Nhập số n > 0. Tính S(n) = 1/2 + 1/4 + … + 1/2n.

Bài 14: Nhập số n > 0. Tính S(n) = 1+ 1/3 + 1/5 + … + 1/(2n+1).

Bài 15: Nhập số n > 0. Tính S(n) = 1/(1*2) + 1/(2*3) + … + 1/(n*(2n+1)).

Bài 16: Nhập số n > 0. Tính S(n) = 1/2 + 2/3 + 3/4 + … + n/(n+1)

Bài 17: Nhập số n > 0. Tính S(n) = 1 * 2 * 3 * … * n

Bài 18: Nhập số n > 0, x > 1. Tính F(x,n) = xn

Bài 19: Nhập số n > 0. Tính S(n) = 1 + (1 * 2) + (1 * 2 * 3)  + … + (1 * 2 * 3  … * n)

Bài 20: Nhập số n > 0, x > 1. Tính S(n) = x + x2/2! + x3/3! + … + xn/n!

Bài 21: Nhập số n > 0, x > 1. Tính S(n) = 1 + x2/2! + x4/4! + … + x2n/(2n)!

Bài 22: Nhập số n > 0, x > 1. Tính S(n) = 1 + x + x3/3! + x5/5! + … + x2n+1/(2n+1)!

Bài 23: Liệt kê tất cả “ước số” của số nguyên dương n.

Bài 24: Tính tổng tất cả “ước số” của số nguyên dương n.

Bài 25: Tính tích tất cả “ước số” của số nguyên dương n.

Bài 26: Liệt kê các “ước số lẻ” và “ước số chẳn” của số nguyên dương n.

Bài 27: Nhập số nguyên dương n > 0. Tính tổng các “ước số” của nó nhưng nhỏ hơn chính nó.

Bài 28: Tìm “ước số” lẻ lớn nhất của số nguyên dương n.

Bài 29:  Số hoàn thiện (hay còn gọi là số hoàn chỉnh, số hoàn hảo) là số nguyên dương có tổng các ước số nguyên dương(ko kể chính nó) bằng chính nó. Nhập một số nguyên dương n. Kiểm tra xem n có là số hoàn thiện hay không

Bài 30: Số nguyên tố là số chỉ chia hết cho 1 và chính nó. Nhập một số nguyên dương n. Kiểm tra xem n có là số nguyên tố hay không.

Bài 31: Số amstrong là số mà tổng lũy thừa bậc n của các chữ số bằng chính nó với n là số chữ số (153 = 1^3 + 5^3 + 3^3). Nhập một số nguyên dương n. Kiểm tra xem n có là số amstrong hay không

Bài 32: Số chính phương hay còn gọi là số hình vuông là số tự nhiên có căn bậc 2 là một số tự nhiên. Nhập một số nguyên dương n. Kiểm tra xem n có là số chính phương hay không.

Bài 33: Tìm USCLN, BSCNN của 2 số a và b.

Bài 34: Tính S(n) = √(2 + √(2 + √(2 + … + √(2 + √2)))), có n dấu căn

Bài 35: Tính S(n) = √(n + √(n-1 + √(n-2 + … + √(2 + √1)))), có n dấu căn

Bài 36: Tính S(n) = √(1 + √(2 + √(3 + … + √(n-1 + √n)))), có n dấu căn

Bài 37: Tính S(n) = √(n! + √((n-1)! + √((n-2)! + … + √(2! + √1!)))), có n dấu căn

Bài 38: nhập số nguyên dương n > 1. Tìm giá trị nguyên k lớn nhất sao cho S(k) < n, với S(k) = 1 + 2 + 3 + .. + k.

Bài 39: Đếm số lượng chữ số của một số nguyên dương n.

Bài 40: Tính tổng/tích các chữ số của một số nguyên dương n.

Bài 41: Đếm số lượng chữ số chẳn/lẻ của một số nguyên dương n.

Bài 42: Tính tổng lẻ và tích chẳn các chữ số của một số nguyên dương n.

Bài 43: tìm số đảo ngược của một số nguyên dương n. Ví dụ: 12 => 21, 1123 => 3211, 56435 => 53465

Bài 44: Tìm chữ số nhỏ nhất/lớn nhất của một số nguyên dương n.

Bài 45: Kiểm tra số nguyên dương n có phải là số đối xứng. Vi dụ: 131, 1221, 14341, 4566654

Bài 46: Viết chương trình in bảng cửu chương từ 1 – 9

Bài 47: Kiểm tra năm nhuận: Biết năm nhuận là năm chia hết cho 400 hoặc chia hết cho 4 nhưng không chia hết cho 100

Bài 48: In dãy fibonacci. Ví dụ: 0, 1, 1, 2, 3, 5, 8, 13….

Bài 49: tính Pi bằng phương pháp Monte Carlo.

Bài 50: Nhập số nguyên dương n. Liệt kê các số chính phương, số nguyên tố, số hoàn thiện, số amstrong nhỏ hơn n