Vấn đề Unicode với Python 3- Oracle

Đối với Python 3 thì string tự động được sử dụng với Unicode nhưng khi sử dụng Tiếng Việt thao tác xuống Database Oracle hoặc hiển thị dữ liệu Tiếng Việt lên thì bị lỗi.

Để khắc phục điều này khi sử dụng connect tới DB thì cần khai báo encoding và nencoding: cx_Oracle.connect(‘admin’,’admin’,dsn_tns,encoding=”UTF-8″, nencoding=”UTF-8″)

Ví dụ hoàn thiện với việc thêm mới dữ liệu Tiếng Việt:

#!/usr/bin/python

# -*- coding: utf8 -*-
from unicodedata import normalize
import cx_Oracle
cursor, connection = None, None
try:
    dsn_tns = cx_Oracle.makedsn('192.168.177.xxx' , 1522, 'orcl')
    connection = cx_Oracle.connect('admin','admin',dsn_tns,encoding="UTF-8", nencoding="UTF-8")
    cursor = connection.cursor()
    a=u"Lý do"
    b="reasons"
    c="INSERT INTO VN_TEMP_DIC (VN, EN,DAY_TIME,STATUS) VALUES ('%s','%s',sysdate,0)" % (a,b)
    cursor.execute(c)
    cursor.execute("COMMIT")
except cx_Oracle.DatabaseError as e:
    raise e
except Exception as e:
    raise e     
finally:
    if cursor != None:
        cursor.close()
    if connection != None:
        connection.close()


    

Ví dụ hoàn thiện với việc hiển thị dữ liệu tiếng Việt load từ DB:

#!/usr/bin/python
# -*- coding: utf8 -*-

import cx_Oracle
dsn_tns = cx_Oracle.makedsn('xxxxxxxxx' , 1522, 'orcl')
connection = cx_Oracle.Connection('admin','admin',dsn_tns,encoding="UTF-8", nencoding="UTF-8")
cur=connection.cursor()
content = 'however it not depend on column INDPOSTPONEADVANTAGES'
listword=content.split()
listr="";
for re in listword:
    listr=listr+"','"+re
listr=listr
listr=listr[3:]   
print(listr)
query="select a.EN,a.VN from VN_TEMP_DIC a where trim(a.EN) in('%s') order by a.STATUS desc,a.DAY_TIME desc" % (listr)
#print(query)
cur.execute(query)
for result in cur:
    print(result[0]+" - "+result[1])
cur.close()
connection.close

Xuất file pdf với python sử dụng thư viện pypdf

Do nhu cầu công việc mình cần tạo file pdf rồi gửi qua email cho mỗi người một file riêng. Trước đây để xuất tất cả dữ liệu ra 1 file pdf bằng birt report sau đó dùng tool cắt file và gửi bằng tay. Hoặc dùng birt report xuất file pdf cho từng người rồi gửi bằng tay…
Bây giờ số người cần gửi tăng lên, mình không thể gửi bằng tay như vậy được nên cần phải làm tự động thao tác này.
Bước cần làm đó là chuẩn bị cơ sở dữ liệu là excel hoặc database, sau đó dùng command line xuất file và gửi email cho từng người. Bước khó khăn đầu tiên và nhiều nhất đó là sử dụng python tự động xuất ra file pdf. Mình quyết định dùng môi trường windown và code bằng python với thư viện pypdf.

Link quan trọng để làm theo: https://www.blog.pythonlibrary.org/2018/06/05/creating-pdfs-with-pyfpdf-and-python/

Các bước quan trọng:

Bước 1: Cài python cho windown (google)
Bước 2: Cài pip cho python
Bước 3: Cài pyfpdf: python -m pip install fpdf
Bước 4: Tải và sử dụng Unicode với pyfpdf: https://pyfpdf.readthedocs.io/en/latest/Unicode/index.html
Đoạn code quan trọng để in ra được tiếng việt: pdf.add_font(‘DejaVu’, ”, ‘DejaVuSansCondensed.ttf’, uni=True)

Thành công khi kết hợp các ví dụ cơ bản trong link trên.

#!/usr/bin/python

# -*- coding: utf8 -*-

from fpdf import FPDF
 
class CustomPDF(FPDF):
 
    def header(self):
        # Set up a logo
        self.image('logo.jpg', 10, 8, 33)
        self.set_font('Arial', 'B', 10)
 
        # Add an address
        self.cell(50)
        self.cell(0, 5, 'CONG TY TNHH A VIET NAM', ln=1)
        self.cell(58)
        self.cell(0, 5, 'Dia chi: Tang 15, Thap A, Toa nha A,', ln=1)
        self.cell(60)
        self.cell(0, 5, '5321 Kim Ma, Ngoc Khanh, Ba Dinh, Ha Noi', ln=1) 
        self.cell(60)
        self.cell(0, 5, 'Tel: (+84-4) 6272 6600 -- Fax: (+84-4) 3771 4781', ln=1) 
        # Line break
        self.ln(8)
        self.cell(40)
        self.cell(0, 5, 'BANG TONG HOP CHIET KHAU THUONG MAI TREN DOANH SO', ln=1) 
        self.cell(60)
        self.cell(0, 5, 'CUA DAI LY BAN LE THANG 01/2019', ln=1) 
	
    def footer(self):
        self.set_y(-10)
 
        self.set_font('Arial', 'I', 8)
 
        # Add a page number
        page = 'Page ' + str(self.page_no()) + '/{nb}'
        self.cell(0, 10, page, 0, 0, 'C')
 
def create_pdf(pdf_path):
	data = [['','','', 'Thông tin tổng đại lý'],
			['','','Tên', 'Cong ty TNHH Thang Lai'],
			['','','Mã', '17000'],
			]
	data1 = [['STT','MA','TEN DAI LY', 'SO LUONG TB MOI','THANH TIEN(VND)'],
				['1','6501','Pham Khac Tuy rat Dep trai lai con hoc gioi', '100','45000'],
				['2','6502','ABC', '200','90000'],
				['2','6502','ABC', '200','90000'],
				['2','6502','ABC', '200','90000'],
				['3','6503','CONG TY TNHH THIET BI VA CONG NGHE NGOC ANH', '200','90000'],
				['','','', 'Tong tien gop','225000']
			]
	data4 = [['','NGUOI LAP BIEU','','KE TOAN TRUONG'],
				['','','',''],
				['','','',''],
				['','','',''],
				['','','',''],
				['','','','NGUYEN THI TO HAO']
				]			
	d2='CÔNG TY TNHH ATM VIỆT NAM'
	d1='CONG TY TNHH ATM TINH VIET NAM'
	d3='Địa chỉ: Tầng 15, Tháp A, Tòa Nhà B,'
	d31='Dia chi: Tang 15, Tháp A, Tòa Nhà B'
	pdf = FPDF()
    # Create the special value {nb}
	pdf.alias_nb_pages()
	pdf.add_page()
	pdf.set_font('DejaVu', '', 12)
	pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
	pdf.set_font('DejaVu', '', 14)
	pdf.image('logo.jpg', x=10, y=8, w=20)
	pdf.set_font('DejaVu', '', 10)
	pdf.cell(200, 5, txt=d2, ln=1, align="C")
	pdf.set_font('DejaVu', '', 8)
	pdf.cell(200, 5, txt=d31, ln=1, align="C")
	pdf.cell(200, 5, txt="521 Kim Ma, Ngoc Khanh, Ba Dinh, Ha Noi.", ln=1, align="C")
	pdf.cell(200, 5, txt="Tel: (+84-4) 6272 6600 -- Fax: (+84-4) 3771 4781", ln=1, align="C")
	pdf.ln(8)
	pdf.set_font('DejaVu', '', 12)
	pdf.cell(200, 5, txt='BANG TONG HOP CHIET KHAU THUONG MAI TREN DOANH', ln=1, align="C")
	pdf.cell(200, 5, txt='SO CUA DAI LY BAN LE THANG 1/2019', ln=1, align="C")
	pdf.ln(8)
	pdf.set_font('DejaVu', '', 10)
	col_width = pdf.w / 4.5
	row_height = pdf.font_size
	for row in data:
		for item in row:
			pdf.cell(col_width, row_height*1,txt=item, border=0)
		pdf.ln(row_height*1)
	pdf.cell(20, 5, txt='Ngay xuat:', ln=1, align="C")
	pdf.ln(8)
	col_width = pdf.w / 5.5
	col_width1 = col_width*1/3
	col_width2 = col_width*1/3
	col_width3 = col_width+col_width*2/3+col_width*2/3
	row_height = pdf.font_size
	i=0
	for row in data1:
		i=i+1
		if i==1:
			j=0
			for item in row:
				pdf.set_font('Times', 'B', 10)
				j=j+1
				if j==1:
					pdf.cell(col_width1, row_height*1.4,txt=item, border=1,ln = 0, align = 'C', fill = False, link = '')
				else:
					if j==3:
						pdf.cell(col_width3, row_height*1.4,txt=item, border=1,ln = 0, align = 'C', fill = False, link = '')
					else:
						if j==2:
							pdf.cell(col_width2, row_height*1.4,txt=item, border=1,ln = 0, align = 'C', fill = False, link = '')
						else:
							pdf.cell(col_width, row_height*1.4,txt=item, border=1,ln = 0, align = 'C', fill = False, link = '')
		else:
			j=0
			for item in row:
				pdf.set_font('Times', '', 10)
				j=j+1
				if j==1:
					pdf.cell(col_width1, row_height*1.4,txt=item, border=1, align = 'C', fill = False)
				else:
					if j==3:
						pdf.cell(col_width3, row_height*1.4,txt=item, border=1, align = 'L', fill = False)
					else:
						if j==2:
							pdf.cell(col_width2, row_height*1.4,txt=item, border=1, align = 'C', fill = False)
						else:
							pdf.cell(col_width, row_height*1.4,txt=item, border=1, align = 'R', fill = False)
		pdf.ln(row_height*1.4)
	line_no = 1
	pdf.ln(8)
	pdf.set_font('DejaVu', '', 10)
	col_width = pdf.w / 4.5
	row_height = pdf.font_size
	for row in data4:
		for item in row:
			pdf.cell(col_width, row_height*1,txt=item, border=0)
		pdf.ln(row_height*1)
#	for i in range(50):
#		pdf.cell(0, 10, txt="Line #{}".format(line_no), ln=1)
#		line_no += 1		
	pdf.output(pdf_path)
 
if __name__ == '__main__':
    create_pdf('header_footer.pdf')

Sử dụng Python kết nối CSDL Oracle bằng Anaconda

Anaconda là 1 tool trên Windown giúp học và sử dụng Python được dễ dàng hơn. Bài viết này sẽ ghi lại các thao tác cài đặt để có thể sử dụng Python kết nối với CSDL Oracle.

  • B1: Chuẩn bị sẵn Anaconda3
  • B2: Cài đặt thư viện cx_oracle làm cầu nối giao tiếp giữa Python và Oracle
    Trong phần quản trị của Anaconda, chọn tab Environments.
    Trong màn hình này chọn All và nhập tìm kiếm cx_oracle
  • B3: Tích chọn vào cv_oracle và ấn Apply. chờ 1 chút để việc cài đặt hoàn tất.
  • B4: Để test, tạo mới một Notebook Jupiter, và nhập thử như sau:
import cx_Oracle
dsn_tns = cx_Oracle.makedsn('192.168.177.xxx' , 1522, 'oracl')
connection = cx_Oracle.Connection('admin','admin',dsn_tns)
ver=connection.version
print('DB version : '+ ver)
cur=connection.cursor()
cur.execute('Select name from v$database')
for result in cur:
    print('DB Name : ' + result[0])
cur.close()
connection.close 

Kết quả hiển thị thành công:

DB version : 11.2.0.4.0
DB Name : ORACL

Phát hiện đối tượng real-time với YOLO

YOLO là một thư viện sử dụng trí tuệ nhân tạo để phát hiện đối tượng real-time trong ảnh và video. Ta có thể sử dụng YOLO với nhiều ngôn ngữ khác nhau như Python, Javascript, C++… YOLO xử lý ảnh có thể sử dụng GPU hoặc OPENCV
Trang chủ của YOLO: https://pjreddie.com/darknet/yolo/#demo

Phát hiện đối tượng với YOLO
Phát hiện đối tượng với YOLO

Cài đặt YOLO trên máy ảo

  • Thiết lập máy ảo CENTOS 7
  • Cài đặt git: sudo yum install git
  • cài đặt GCC: # yum group install “Development Tools”
  • Clone project darknet: git clone https://github.com/pjreddie/darknet
  • Cài đặt OPEN CV
    yum install cmake gcc gtk2-devel numpy pkconfig -y
    cd
    wget https://github.com/opencv/opencv/archive/3.4.2.zip
    unzip 3.4.2.zip
    https://www.vultr.com/docs/how-to-install-opencv-on-centos-7
  • Sửa file Makefile dòng OPENCE từ 0 thành 1
  • Biên dịch darknet:
    cd darknet
    make
  • Tải trọng số có sẵn đã được train: wget https://pjreddie.com/media/files/yolov3.weights
  • Test: ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

Một số địa chỉ tham khảo:

https://www.blog.pythonlibrary.org/2018/06/05/creating-pdfs-with-pyfpdf-and-python/

https://pjreddie.com/darknet/yolo/#demo

https://www.vultr.com/docs/how-to-install-opencv-on-centos-7

Dùng python call webservice XML SOAP

Sau một hồi vật vã tìm kiếm thì mới tìm thấy cách sử dụng python để gọi một 1 webservice XML sử dụng SOAP.
Webservice XML được tạo ra bởi .NET và sử dụng .NET để gọi thì đơn giản rồi. Bây giờ mình muốn sử dụng Python thì cũng khá phức tạp, tìm mãi mới thấy cách dùng:

Code:

import requests
url="http://xxx.xxx.xxx:8668/xxx/WHOLESALESTATISTIC.asmx?WSDL"
#headers = {'content-type': 'application/soap+xml'}
headers = {'content-type': 'text/xml'}
body = """<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body><WholesaleStatistic xmlns="http://tempuri.org/">  <Account>xxx</Account> <Password>pass@abc</Password> <sDate>2019-02-17</sDate></WholesaleStatistic>  </soap:Body></soap:Envelope>"""

response = requests.post(url,data=body,headers=headers)
print(response.content)

Kết quả sẽ trả về định dạng XML, từ đây có thể lấy dữ liệu ra bằng cách pase XML hoặc google…

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><WholesaleStatisticResponse xmlns="http://tempuri.org/"><WholesaleStatisticResult><newsubs>0</newsubs><deactivated>0</deactivated><portfolio>20</portfolio></WholesaleStatisticResult></WholesaleStatisticResponse></soap:Body></soap:Envelope>'

Một số link tham khảo thêm:

https://medium.com/@adriennedomingus/using-zeep-to-make-soap-requests-in-python-c575ea0ee954

https://www.geeksforgeeks.org/get-post-requests-using-python/

https://viblo.asia/p/xay-dung-mot-restful-api-don-gian-voi-python-va-flask-bJzKmMvDK9N

http://hoctuduylaptrinh.com/category/lap-trinh/lap-trinh-python/