MySQL 笔记

创建新用户 create a new user

mysql> create user 'someuser'@'localhost' identified by 'somepassword';

创建新数据库 create new database

mysql> create database some_db_name

赋予用户使用权利 Grant privileges to a user

mysql> GRANT ALL PRIVILEGES ON database_name.* TO 'some_user'@'localhost';

参考资料

MySQL功能非常齐全,每个命令都有很多细节,本文只收集一下基本用法,更多可以看这个网页和官方文档。

Python/Pandas实战: 处理IBKR Statement

Python/Pandas实战: 处理盈透Statement

Pandas是一个非常强大的数据分析方面的Python package. 如果是做Machine Learning或者数据分析, 掌握Pandas很省去很多麻烦. 许多Machine Learning前期的数据处理也是用Pandas做得.

IBKR(Interactive Brokers, 有时简称IB, 中文叫盈透证券)是美国老牌券商, 也是我的主要使用的券商. 又到了辞旧迎新的时候, 需要看看2020投资收益, 于是趁新年长周末写点小程序做点数据分析. 而这正好覆盖了Pandas的各种常用functions.

下载IB Statement

IB Statement提供多种方式下载, 比如html, pdf, csv. 用作数据处理选csv. 内容大概长这样

IB statement例子

Statement这个column是内容, 里面有很多项, 而这里我只看“Realized & Unrealized Performance Summary”, 然后相同的第一列后面的列数都是一样的. 上图是Jupyter Lab的显示有问题. 因为文件其实可以看成很多CSV files连在一起, 而第一列可以看成是小csv的文件名. 然后第二列是Header或者Data. Header那行就是告诉你后面的Data行里每一列都是什么. 于是我们可以把数据读到内存里.

建立Pandas DataFrame

import pandas as pd

field = 'Realized & Unrealized Performance Summary'

f = open('statement.csv', 'r')

rows = []
for line in f:
    cols = line.strip().split(',')
    if cols[0] == field:
        if cols[1] == 'Header':
            header_row = cols[2:]
        else:
            rows.append(cols[2:])

header_ros是个list of string

['Asset Category',
 'Symbol',
 'Cost Adj.',
 'Realized S/T Profit',
 'Realized S/T Loss',
 'Realized L/T Profit',
 'Realized L/T Loss',
 'Realized Total',
 'Unrealized S/T Profit',
 'Unrealized S/T Loss',
 'Unrealized L/T Profit',
 'Unrealized L/T Loss',
 'Unrealized Total',
 'Total',
 'Code']

而rows是list of list. 就是list of rows

[['Stocks',
  'AAPL',
  '0',
  '0',
  '0',
  '0',
  '0',
  '0',
  '29564.510608',
  '-14.176325',
  '0',
  '0',
  '29550.334283',
  '29550.334283',
  '\n'],
 ['Stocks',
  'AMD',
  '0',
  '0',
  '0',
  '0',
  '0',
  '0',
  '220.208447',
  '0',
  '0',
  '0',
  '220.208447',
  '220.208447',
  '\n'],
...
]

接下来就可以用Panda create dataframe了

df = pd.DataFrame(rows, columns = header_row)
df.head(5)

这里有个问题. Created出来的dataframe的数据类型有数字有string, 全部都是object. 如果sort by数字column得到的结果是sort by string, 并不是我们想要的. 可以用dtypes来确定

df.dtypes
Asset Category           object
Symbol                   object
Cost Adj.                object
Realized S/T Profit      object
Realized S/T Loss        object
Realized L/T Profit      object
Realized L/T Loss        object
Realized Total           object
Unrealized S/T Profit    object
Unrealized S/T Loss      object
Unrealized L/T Profit    object
Unrealized L/T Loss      object
Unrealized Total         object
Total                    object
Code                     object
dtype: object

这里我把需要转换成数字的columns转换了

header_text_col = set(['Asset Category', 'Symbol', 'Code'])
num_col = list(set(header_row) - header_text_col)
df[num_col] = df[num_col].apply(pd.to_numeric)
df.dtypes
Asset Category            object
Symbol                    object
Cost Adj.                  int64
Realized S/T Profit      float64
Realized S/T Loss        float64
Realized L/T Profit        int64
Realized L/T Loss        float64
Realized Total           float64
Unrealized S/T Profit    float64
Unrealized S/T Loss      float64
Unrealized L/T Profit      int64
Unrealized L/T Loss      float64
Unrealized Total         float64
Total                    float64
Code                      object
dtype: object

这样就可以对数字类型的column进行排序了, 比如下面指令做2步操作
1. 选出Asset Category是”Stocks”的rows, 相当于SQL里的where, 语法为df[df['Asset Category'] == 'Stock'], return是另一个filtered好的dataframe
2. 按Realized Total从小到大排序, return也是另一排序好的dataframe

df[df['Asset Category'] == 'Stock'].sort_values(by=['Realized Total'], ascending=True)

还可以画图

stock_gain = df[
    (df['Asset Category'] == 'Stocks') & (
        df['Realized Total'] != 0.0)][['Symbol', 'Realized Total']].sort_values(
    by=['Realized Total'], ascending=True)
stock_gain

还可以画图

stock_gain.plot.bar(x='Symbol')

技术小结

建立dataframe

rows是list of rows(lists), header_row是list of string

df = pd.DataFrame(rows, columns = header_row)

显示前n行

df.head(10)

显示后面n行

df.tail(10)

把特定columns转换成数字(numerical type)

num_col是list of strings, 下面命令会把num_col里的columns都转化成数字类. 类似SQL里的select cast(col1 as double), cast(col2 as double), ... from df

df[num_col] = df[num_col].apply(pd.to_numeric)

Filter和sort

类似SQL里, select * from df where asset_category = 'Stocks' order by realized_total asc;

df[df['Asset Category'] == 'Stocks'].sort_values(by=['Realized Total'], ascending=True)

在Apache2里怎样redirect URL? | How to redirect URL using Apache2?

在Apache2里怎样redirect URL?

原来以为这个问题很简单, Google了一下发现网上的答案五花八门, 而且版本很混乱 有httpd的, ASP.net, url redirect的, url rewrite的. 经过多次尝试各种组合, 终于试出了一个可行的解决方案, 值得在此记录一下, 相信一定能帮到有类似需求的人. 本文例子为Ubuntu + apache2, 2020年, 2021年左右.

普通URL redirect到另一个网站

编辑/etc/apache2/sites-available里面的一个site, 比如mysite, 需要redirect到anothersite.com, 那么可以加上一行Redirect

<VirtualHost *:80>
ServerAdmin webmaster@localhost
...
         ServerName mysite.com
         ServerAlias www.mysite.com
         DocumentRoot /var/www/html/mysite
         Redirect / http://anothersite.com
...         

修改完成后保存, 重启apache2

sudo service apache2 restart

Redirect到一个子目录

上面的方法可以redirect到不同的URL, 但是如果想redirect mysite.com到mysite.com/blog就不行. 我试了一下, 如果像上面那样改动, 在浏览器输入mysite.com就会被不停的改成mysite.com/blog/blog/blog… 无限循环. 很明显, 改写是recursive的. 那么就不要用Redirect而是用RedirectMatch

<VirtualHost *:80>
ServerAdmin webmaster@localhost
...
         ServerName mysite.com
         ServerAlias www.mysite.com
         DocumentRoot /var/www/html/mysite
         RedirectMatch ^/$ /blog/
...       

我也不太清楚apache2配置的语法细节, 但是以上是试过可行的方法. 最后一样是重启apache2让配置生效

sudo service apache2 restart

怎样给wordpress网站创建XML sitemap?

how to create a wordpress sitemap

XML sitemap是什么?

简单来说, XML sitemap是一个网站包含网页的列表. 它的目的是让搜索引擎, 主要是Google的爬虫能发现这个站点并把站点内的网页添加到搜索索引里. 一个新建的网站几乎是网络里的孤岛, 没有任何其他网站指向它, 所以如果想被Google收录并索引的话, sitemap是很重要的.

怎样创建一个XML sitemap?

如果使用Wordpress的话, 可以使用Yoast SEO插件生成一个XML sitemap.

安装Yoast SEO插件

在Wordpress管理后台选择Plugins, 然后Add new

搜索Yoast SEO, 然后点击Yoast SEO结果上的Install Now, 完成后, 点击Active, 如下图

用Yoast SEO生成XML sitemap

在Wordpress后台选择SEO, 然后general

选择Features tab, 确保XML sitemaps是ON的, 然后Save Changes

确认Sitemap成功生成

做完以上步骤以后, Sitemap的URL应该是<my site>/index.php/sitemap_index.xml. 比如本站feellikelearning.com/index.php/sitemap_index.xml 如下图

怎样解决PHP找不到mb_convert_encoding函数? | How to solve the problem of php can’t find mb_convert_encoding function?

问题描述

本来想解决Wordpress不支持中文URL问题的. 网上大部分的帖子都是大同小异, 比如知乎这篇. 简单来说就是在wp-includes/class-wp.php里把url的encoding从UTF-8换成GBK. 我照着修改后并不行. 先遇到PHP找不到mb_convert_encoding这个函数, 后来解决了. 虽然最后中文URL还是没搞定, 这里记录一下怎么解决mb_convert_encoding找不到的问题的解决方法.

PHP 里找不到 mb_convert_encoding 函数的解决方法

首先安装 php-mbstring, 比如Ubuntu里

sudo apt-get install php-mbstring

然后重启web server, 比如 Apache2

sudo service apache2 restart

验证 mb_convert_encoding 安装成功

用PHP的REPL

$ php -a
php > $s = mb_convert_encoding('abc', 'UTF-8', 'GBK');
php > print $s;
鎮ㄥソ

php > $s = mb_convert_encoding($s, 'GBK', 'UTF-8');
php > print $s;
您好

可见 mb_convert_encoding 函数可以在PHP里正常使用了.

怎样解决WordPress需要ftp账号问题 | how to solve the “ftp account” problem in WordPress

问题描述

WordPress没设置好的时候, 如果直接安装插件, 主题都会提示需要输入ftp账号, 密码之类. 如下图所示

当然, 手动安装是一直可以的, 就是下载好然后上传到后台文件系统, 比如用sftp, 然后用ssh登陆后解压, 把文件目录拷贝到相应的路径里, 比如插件在wp-content/plugins里, 主题在wp-content/themes里. 就是比较麻烦, 每次更新都要重复操作. 其实只要修改一下设置, 就可以完全在Dashboard用图形界面完成升级, 安装等操作.

怎样修改设置?

在Wordpress安装目录下的wp-config.php里加入这么一行.

define('FS_METHOD' , 'direct');

这个文件基本都是一堆define(…); 加哪里无所谓, 和其他define平行就行.

然后修改Wordpress安装目录文件系统权限

chmod -R 777 <wordpress install path>

做了以上修改以后, 应该就可以不用看到提示需要ftp account的提示了.

算法练习 Leetcode 力扣 416. Partition Equal Subset Sum 使用0-1背包问题 2维dp模版的 Python 解法

问题描述

这题的最优解是使用Bottom up DP, 题目描述和详细解法可以参考这篇文章. 本文示范一下这题也可以直接使用这篇文章总结的0-1背包问题2维dp模版一字不改直接解

0-1背包问题2维度dp模版解法

Continue reading “算法练习 Leetcode 力扣 416. Partition Equal Subset Sum 使用0-1背包问题 2维dp模版的 Python 解法”

动态规划算法 – 0-1 背包问题 Python 讲解| Dynamic Programming Algorithm – 0-1 knapsack problem explained in Python

0-1 背包问题 Python讲解

问题描述

有N个物品, 每个物品Cost为C[i], Value为W[i], 其中 i 属于 [0, …, N-1]
有一个书包, 容量为V
求书包能装下的最大Value

为什么叫0-1背包?

Continue reading “动态规划算法 – 0-1 背包问题 Python 讲解| Dynamic Programming Algorithm – 0-1 knapsack problem explained in Python”