解决公司电脑无法更新问题

公司发的mac book,是m1芯片,但因为数据安全问题,对于部分权限做了限制,如:无法进行系统更新,需要拿到it部门解决。

前几天我打算重启python编程训练,发现无法安装numpy。

过了两天,灵机一动,在虚拟环境下,venv里进行安装

首先激活虚拟环境

 . venv/bin/activate

然后,在虚拟环境下更新pip

  python -m pip install --upgrade pip
  Requirement already satisfied: pip in ./venv/lib/python3.8/site-packages (22.0.4)

最后,安装numpy

  pip3 install numpy  
  Requirement already satisfied: numpy in ./venv/lib/python3.8/site-packages (1.22.3)

退出虚拟环境

  deactivate 

Flask@002

“By default Flask looks for templates in a templates subdirectory 
located inside the main application directory. For the next version of 
hello.py, you need to create the templates subdirectory and store the 
templates defined in the previous examples in it as index.html and 
user.html, respectively.”

Excerpt From
Flask Web Development
Miguel Grinberg
This material may be protected by copyright.

按照狼书的说明,使用templates的好处是,把业务逻辑和代码的呈现逻辑进行了隔离,这样的好处是非常清晰,不会让程序员的思路混乱,当使用git checkout 3a后,检查目录结构如下:

(venv) MDMacPro/Users/madapapa/Study/madapapa.com/flaskr/flaskproject/
flaskygit:(e020af8) [12:20]ls
LICENSE     __pycache__ templates
README.md   hello.py

debug mode

“(venv) $ export FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1
(venv) $ flask run”

Excerpt From
Flask Web Development
Miguel Grinberg
This material may be protected by copyright.

通过export FLASK_DEBUG=1开启debug模式,有两个好处

  • reloader模式可以在修改源代码的同时,自动重启服务器,代码的修改结果在运行环境下自动生效,对调试非常友好
  • debugger模式,可以让你的浏览器显示错误信息,不过在生产环境下绝对不能打开这个模式。

template和placeholder

template是包含了响应内容的文件,使用placeholder作为一个变量服务动态部分,这个动态部分包含在请求的文本里。使用实际值来代替变量,并且返回最终响应字符串的过程,就是渲染(rendering),flask使用一个非常强大的模版引擎:Jinja2。

Jinja是日语神庙的意思。

render_template函数

render_template函数使用Jinja2引擎,第一个参数是文件名“index.html”,第二个参数是一个key-values的键值对,其中na是user.html中的参数名称,name1是需要带入的真实参数值。

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/user/<name1>')
def user(name1):
    return render_template('user.html', na=name1)

user.html文件的内容

<h1>Hello, {{ na }}!</h1>

{{na}}这种结构,可以带入各种参数格式,比如字典、列表、方法等等。

“<p>A value from a dictionary: {{ mydict['key'] }}.</p>
“<p>A value from a list: {{ mylist[3] }}.</p>”
“<p>A value from a list with variable index:{{ mylist[myvar] }}.</p>”
“<p>A value from an object's method: {{ myobj.somemethod() }}.</p>”

开始flask001

flask虚拟环境

根据flask官网介绍,使用虚拟环境来管理项目的依赖,包括开发与生产环境。

因为随着Python项目增多,很有可能要与不同的python库、甚至不同版本的python打交道。一个项目的新版本库文件与另外一个项目可能不兼容。

虚拟环境独立于python库,一个虚拟环境匹配一个项目。为一个项目安装的包不会影响其他项目包或系统包。

Python绑定venv模块来创造虚拟环境。

创建虚拟环境

macOS/Linux

$ mkdir flaskproject
$ cd flaskproject
$ python3 -m venv venv

激活虚拟环境

macOS/Linux

$  . venv/bin/activate

这里需要注意,这个“.”和venv之间要有空格,参见stackoverflow的解释:

. venv/bin/activate

or

source venv/bin/activate

使用虚拟环境,并设置为开发环境

在venv环境下,如果直接启动flask服务:

flask run

会有如下红色警告信息,因为flask默认开发者是生产环境下工作,而开发环境不稳定,所以会提示如下告警。
Screen Shot 2021-12-20 at 12.00.48 AM

因此需要进行设置

(venv) MDMacPro/Users/XXXXXXXXXXXX/flaskr/flaskproject/bmi[23:58]export FLASK_ENV=development

参考flask设置环境变量

使用git checkout 2a

使用git checkout 2a 把对应project的source code复制到visual studio里面

由于已经通过git启动了相关程序,因此会展示如下内容。

使用git reset –hard

如果对git上的源代码进行了修改,可以使用git reset –hard放弃所有修改

(venv) MDMacPro/Users/madapapa/Study/madapapa.com/flaskr/flaskproject/flaskygit:(32acca2) ✗ [12:07]git reset --hard
HEAD is now at 32acca2 Chapter 2: Dynamic routes (2b)
(venv) MDMacPro/Users/madapapa/Study/madapapa.com/flaskr/flaskproject/flaskygit:(32acca2) [12:09]git checkout 3a
Previous HEAD position was 32acca2 Chapter 2: Dynamic routes (2b)
HEAD is now at e020af8 Chapter 3: Templates (3a)

解决VS code无法远程写入(写入管道不存在)

使用VS code的remote ssh功能,昨天在mac电脑上一切顺利。今天在设置办公室的windows10,遇到如下报错(使用了参考1文章里的内容,因为我解决问题后,没法复现)

[14:18:57.722] Got some output, clearing connection timeout
[14:18:57.751] > 过程试图写入的管道不存在。
[14:18:58.010] "install" terminal command done
[14:18:58.011] Install terminal quit with output: 过程试图写入的管道不存在。
[14:18:58.011] Received install output: 过程试图写入的管道不存在

解决方法很简单,按照参考文章的建议,将ssh目录下(C:\Users\XXXXX.ssh\known_hosts)的known_hosts文件内记录的服务器信息删除,任何文本编辑器打开后做如下操作,当然不是真的删除,屏蔽就好。

当然,也走了弯路,第一次按照参考2文章去做了修改,发现无效。不过这篇文章也提供了VS Code SSH本地配置文件的修改方法,也算有些用处。

参考1

参考2

套接字python2和python3不同

编写web应用服务器报,TypeError: a bytes-like object is required, not ‘str’错误。
因为python2和python3的版本有些差异,而python3最重要的新特性也是对文本和二进制数据做了更清晰的区分。

文本用unicode编码,为str类型,二进制数据则为bytes类型

python2的例子

import socket,sys 

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#code=str.encode('GET /api.json HTTP/1.0\r\n\r\n')
#s.send(code)
s.send('GET /api.json HTTP/1.0\r\n\r\n')

while 1:
    buf = s.recv(1000)
    if not buf:
        break
    sys.stdout.write(buf)

s.close()

在python2的环境下运行,执行结果如下
Screen Shot 2021-11-14 at 2.45.47 PM

python3的例子

import socket,sys 

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#s.send(str.encode('GET /api.json HTTP/1.0\r\n\r\n'))
s.send('GET /api.json HTTP/1.0\r\n\r\n'.encode())


while 1:
    buf = s.recv(1000).decode()
    #s1 = buf.decode()
    if not buf:
        break
    sys.stdout.write(buf)

s.close()

在默认环境下运行(python3),执行结果如下

附录

套接字

套接字是一套用C语言写成的应用程序开发库,它首先是一个库。主要作用就是实现进程间通信和网络编程,因此在网络应用开发中被广泛使用。

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

在Python中可以基于套接字来使用传输层提供的传输服务,并以此进行开发网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字和原始套接字。

流式套接字

流式套接字(SOCK-STREAM)。它提供了一种可靠的、可以进行双向连接的数据传输服务。其实现了数据无差错、无重复的发送。流式套接字自身便内设了流量控制功能。在TCP/IP协议簇中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。

数据报套接字

数据报套接字(SOCK-DGRAM)。它提供了一种不可靠的双向数据传输服务。数据包以独立的形式被发送,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在TCP/IP协议簇中,使用UDP协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。

原始套接字

原始套接字(SOCK-RAW)。该套接字允许对较低层协议(如IP或ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。

上述就是套接字的大体知识,对套接字有了一定的了解,我们就可以步入正题了。

TCP套接字

TCP套接字就是上面所说的流式套接字,可以使用TCP协议提供的传输服务来实现网络通信的编程接口。

在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。

由于一台主机可能拥有多个IP地址,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的IP地址和端口上。

这个端口是指对IP地址的扩展,用于区分不同的服务。

不同的服务通常与相对的端口所绑定。

当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是何种服务。

关于服务于端口的绑定类型,我们会在之后的开发的当中具体描述。

如何用Python设置一个客户端的功能,简易代码如下:

fromsocketimportsocket

def main():

1.创建套接字对象默认使用IPv4和TCP协议

client= socket()

2.连接到服务器 ,指定IP地址和端口

client.connect((‘192.168.1.8’, 1080))

3.从服务器接收数据

print(client.recv(1024).decode(‘utf-8’))

client.close()

if__name__ == ‘main‘:

main()

上述代码就实现了客户端的功能,它可以与服务器进行通信。当然,上述代码只能作为一个最简单的客户端构建方式。更复杂的构建方式,学记将在之后的学习中为大家继续介绍。

一个小小的API测试

在根目录下,编辑一个测试用的api小文件,然后通过浏览器(safari和chrome,地址为本地电脑地址)、终端curl(分别从vps和本地进行)的方式获取该文件。

vi /var/log/nginx/access.log

来查看刚才的api文档的获取记录

139.XXXXX - - [13/Nov/2021:14:34:22 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "curl/7.68.0"(VPS方式)
223.XXXXX - - [13/Nov/2021:14:35:19 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "curl/7.77.0"(本机方式)
223.XXXXX - - [13/Nov/2021:14:36:28 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"(本机方式)
223.XXXXX - - [13/Nov/2021:14:36:28 +0800] "GET /favicon.ico HTTP/1.1" 404 188 "http://madapapa.com/api.json" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"(本机方式)

下面是刚刚发布了这篇blog后的日志变化情况,可以看到从本机进行了post操作

223.XXXXX - - [13/Nov/2021:14:59:24 +0800] "POST /wordpress/xmlrpc.php HTTP/1.1" 200 3493 "-" "MWeb%20Pro/917 CFNetwork/1325.0.1 Darwin/21.1.0"

CentOS7 与 Ubantu20 默认首页的不同

CentOS7-banwagong

首先,nginx -t发现正确配置文件地址

 [11:10]/nginx -t    
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

然后vi nginx.conf,发现根目录为 /usr/share/nginx/html,编辑index.html即可

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
server {
 listen       80;
 root   /usr/share/nginx/html;
 server_name  localhost;
 #charset koi8-r;
 #access_log  /var/log/nginx/log/host.access.log  main;
 #
 location / {
      index index.php index.html index.htm;

Ubuntu20-aliyun

前序操作和centos相仿,在nginx.conf下没有index.html内容,需要对sites-available下default进行编辑

/etc/nginx/sites-available
 # vi default
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;

        server_name _;

ubuntu nginx配置参考

plt.show无法显示图片,imread与random.randint生成narray数组的区别

使用np.random.randint生成了数组,但是没法像读取图像后生成的数组,使用plt.show显示图片显示如下错误(估计使用pil图像也是如此)

> Unsupported depth of input image:
>     'VDepth::contains(depth)'
> where
>     'depth' is 4 (CV_32S)

初步分析,应该是与数据类型相关

对比imread与randint生成数组的数据类型

首先,我们看使用randint生成的数组数据类型

img4Random = np.random.randint(0,256,1200,dtype= 'i')
bgrImg4Random  = img4Random.reshape(20,20,3)

这里生成的数组,每个元素的范围是从0~255,但是数据类型是int32(dtype=‘i’)

print(bgrImg4Random[0,0])
print(bgrImg4Random[0,0,0])
print(bgrImg4Random[0,0,1])
print(bgrImg4Random[0,0,2])
type(bgrImg4Random[0,0,2])

显示结果如下

[ 20 103  51]
20
103
51
numpy.int32

如果省略dtype参数,默认数据类型是int64

img4Random = np.random.randint(0,256,1200)

显示结果如下

numpy.int64

现在我们看看从jpg生成的数组情况,如下

img1 = cv2.imread("ls.jpg")
print(img1[0,1,0])
type(img1[0,0,0])

数据类型是 unit8,也可以用print(image1.dtype)来显示数据类型

33
numpy.uint8

转换数组的数据类型

使用np.unit8或者astype两种方式都可以进行转换到unit8

bgrImg4Random  = img4Random.reshape(20,20,3)
#bgrImg4Random = np.uint8(bgrImg4Random)
#bgrImg4Random=bgrImg4Random.astype(np.uint8)

图像显示出来了,随机的3通道图像,20*20个像素
Screen Shot 2021-03-06 at 2.37.07 PM

参考

数据读入就是unit8,使用np.unit8转换,这里介绍了pil图像,暂时我没有使用过;
解释opencv灰度图和RGB图数据类型,int是32位,而8位就足够了,采用int会浪费存储空间。
介绍opencv处理图像使用unit8

pip3使用国内源更新&解决futu-api库安装问题

方法1

使用如下命令。

python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip

但是在安装futu-api时,总是报错,如下
Screen Shot 2021-02-21 at 18.52.38

分析核心问题应该是

WARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.
You should consider upgrading via the '/usr/local/opt/python@3.9/bin/python3.9 -m pip install --upgrade pip' command.

采用方法1的时候,很有可能并没有更新pip3,还是在错误的目录下下载文件。
所以需要首先确定pip3的版本最新,那么只有进行全局变量的配置,见方法2

方法2

mac和linux配置方法相同

mkdir ~/.pip
vi ~/.pip/pip.conf

在文件中粘贴如下内容,用科大源替换也可以。

[global]
 
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
 
trusted-host = pypi.tuna.tsinghua.edu.cn

然后升级

sudo pip3 install --upgrade pip

Screen Shot 2021-02-21 at 19.01.32

参考
替换pip国内源
替换pip国内源/tencent

国内的pip源

阿里云:https://mirrors.aliyun.com/pypi/simple/
清华:https://pypi.tuna.tsinghua.edu.cn/simple
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/

解决No module name ‘futu’问题

运行futu给的demo代码,总是出现如下错误,找不到futu api这个库
Screen Shot 2021-02-21 at 22.35.10
但是采用python2调用时,则没有类似告警。
这基本可以判断,问题是mac上有两套python环境导致的(mac自带python2环境)。
解决方法如下

  1. 在python3下运行如下代码,获得python3的interpreter路径

    >>> import sys
    >>> print(sys.executable)
    /usr/local/opt/python@3.9/bin/python3.9
  2. 在命令行下(注意,不是python环境下),进入interpreter路径执行安装futu-api命令
    不过这里我也没有搞懂,为什么不适用pip3也能安装成功

    ➜ /usr/local/opt/python@3.9/bin/python3.9 -m pip install futu-api
    

    下面则是执行demo代码成功的结果。
    Screen Shot 2021-02-21 at 22.45.57

参考
富途Q&A