0%


title: Dino Run
tags: tip—

强化学习训练把dino run玩到4000分,教程链接,需要云服务器,所以放弃了。

在网上找到了外挂的方法:https://blog.csdn.net/weixin_41474364/article/details/85613923

根据判断X轴方向小恐龙和前面物品距离进行自动跳跃,添加了代码避免小恐龙跳过蛋糕、避而不吃,调整了对障碍物需要跳跃的高度判断,防止小恐龙看到低飞的鸟儿迎面而上,还有能够在代码执行后,自动开始游戏。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function TrexRunnerBot() {

const makeKeyArgs = (keyCode) => {
const preventDefault = () => void 0;
return {keyCode, preventDefault};
};

const upKeyArgs = makeKeyArgs(38);
const downKeyArgs = makeKeyArgs(40);
const startArgs = makeKeyArgs(32);

if (!Runner().playing) {
Runner().onKeyDown(startArgs);
setTimeout(() => {
Runner().onKeyUp(startArgs);
}, 500);
}

function conquerTheGame() {
if (!Runner || !Runner().horizon.obstacles[0]) return;

const obstacle = Runner().horizon.obstacles[0];

if (obstacle.typeConfig && obstacle.typeConfig.type === 'SNACK') return;

if (needsToTackle(obstacle) && closeEnoughToTackle(obstacle)) tackle(obstacle);
}

function needsToTackle(obstacle) {
return obstacle.yPos !== 50;
}

function closeEnoughToTackle(obstacle) {
return obstacle.xPos <= Runner().currentSpeed * 18;
}

function tackle(obstacle) {
if (isDuckable(obstacle)) {
duck();
} else {
jumpOver(obstacle);
}
}

function isDuckable(obstacle) {
return obstacle.yPos === 50;
}

function duck() {
Runner().onKeyDown(downKeyArgs);

setTimeout(() => {
Runner().onKeyUp(downKeyArgs);
}, 500);
}

function jumpOver(obstacle) {
if (isNextObstacleCloseTo(obstacle))
jumpFast();
else
Runner().onKeyDown(upKeyArgs);
}

function isNextObstacleCloseTo(currentObstacle) {
const nextObstacle = Runner().horizon.obstacles[1];

return nextObstacle && nextObstacle.xPos - currentObstacle.xPos <= Runner().currentSpeed * 42;
}

function jumpFast() {
Runner().onKeyDown(upKeyArgs);
Runner().onKeyUp(upKeyArgs);
}

return {conquerTheGame: conquerTheGame};
}

let bot = TrexRunnerBot();
let botInterval = setInterval(bot.conquerTheGame, 2);

将代码复制到console,回车,会自动进行跳跃,获取分数的速度依然和正常游玩的玩家是一样的,小恐龙走一步记一分。

下面的方法,可以在短时间内迅速加分:

1
2
3
Runner.instance_.setSpeed(99999); 试试 瞬间 满分
window.tempGameOver = Runner.instance_.gameOver;
Runner.instance_.gameOver = function(){}// 不会死亡

npm

npm其实是Node.js的包管理工具(package manager)

安装过程中遇到的问题:

1
npm ERR! audit No package.json found: Cannot audit a project without a package.json

是没有json文件的问题

解决:输入

1
npm init --yes

yii将提示改为中文

例如验证是否为空的提示,可以在common\config\main.php中加 ‘language’=>’zh-CN’,与components同级

另外,修改时区可使用’timeZone’=>’Asia/Shanghai’,

例如提示密码或用户名错误的提示,可在common\models\LoginForm.php文件中修改

发现windows可以很方便地生成文件树,方法如下:

cmd进入在当前目录,执行命令:

tree /F > 文档结构图.txt

小结
要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

小结
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。
Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
git@github.com:michaelliao/gitskills.git
https://github.com/michaelliao/gitskills.git

小结
Git鼓励大量使用分支:
查看分支:git branch
创建分支:git branch
切换分支:git checkout
创建+切换分支:git checkout -b
合并某分支到当前分支:git merge
删除分支:git branch -d

小结
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,
再git stash pop,回到工作现场。

小结
开发一个新feature,最好新建一个分支;
如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。

小结
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log –graph命令可以看到分支合并图。

小结
Git分支十分强大,在团队开发中应该充分应用。
合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,
能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

小结
查看远程库信息,使用git remote -v;
本地新建的分支如果不推送到远程,对其他人就是不可见的;
从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联,使用git branch –set-upstream branch-name origin/branch-name;
从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

小结
命令git tag 用于新建一个标签,默认为HEAD,也可以指定一个commit id;
命令git tag -a -m “blablabla…”可以指定标签信息;
命令git tag可以查看所有标签

小结
命令git push origin 可以推送一个本地标签;
命令git push origin –tags可以推送全部未推送过的本地标签;
命令git tag -d 可以删除一个本地标签;
命令git push origin :refs/tags/可以删除一个远程标签。

小结
在GitHub上,可以任意Fork开源仓库;
自己拥有Fork后的仓库的读写权限;
可以推送pull request给官方仓库来贡献代码。

Yii2 girdView文本溢出显示…

[
​ ‘attribute’=>’content’,
​ ‘label’=>’内容’,
​ ‘format’=>’raw’,
​ ‘value’=>function($model){
​ return “

“.$model->content.”
“;
​ //
​ },

],

只查看数据,消除删除和编辑图标

1
2
3
4
[
'class'=>'yii\grid\ActionColumn'
'template'=>'{view}'
],

控制器向视图传递参数

控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function actionIndex()
{
$view = Yii::$app->view;
$date=(new Query())->from('visit_count')->select('date')->orderBy('date')->all();
foreach($date as $eachdate)
{
$result1[] = $eachdate['date'];
}
$view->params['data1'] = $result1;
$count=(new Query())->from('visit_count')->select('nums')->orderBy('date')->all();
foreach($count as $eachcount)
{
$result2[] = $eachcount['nums'];
}
$view->params['data2'] = $result2;

return $this->render('index');
}

视图:(使用echarts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
use Hisune\EchartsPHP\ECharts;
$this->title = '访问量统计';
$chart = new ECharts();
$chart->tooltip->show = true;
$chart->legend->data[] = '访问量';
$t = $this->params['data1'];
$chart->xAxis[] = array(
'type' => 'category',
'data' => $t
);
$chart->yAxis[] = array(
'type' => 'value'
);
$k = $this->params['data2'];
$chart->series[] = array(
'name' => '访问量',
'type' => 'line',
'data' => $k
);
echo $chart->render('simple-custom-id');
?>

管理员修改密码的功能

弹出消息框:

在view文件中加:

1
Yii::$app->session->getFlash('error');

在model文件中加:

1
Yii::$app->getSession()->setFlash('error','旧密码错误');

修改密码:

model文件:PasswordForm.php,主要用到validatePassword()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
namespace backend\models;

use Yii;
use common\models\Adminuser;
use yii\base\Model;

/**
* Password form
*/
class PasswordForm extends Adminuser
{
public $oldpwd;
public $newpwd;

/**
* {@inheritdoc}
*/
public function rules()
{
return [
//验证规则
];
}

public function changePassword()
{
if (!$this->validate()) {
return null;
}

$id = YII::$app->user->id;
$admin= Adminuser::findIdentity($id);
$password = $admin->password_hash;
if(Yii::$app->getSecurity()->validatePassword($this->oldpwd, $password)){
$newpwd = Yii::$app->getSecurity()->generatePasswordHash($this->newpwd);
$admin->password_hash = $newpwd;

if($admin->save()){
Yii::$app->getSession()->setFlash('success', '修改成功');
return true;
}else{
return false;
}
}
else{
Yii::$app->session->setFlash('error','旧密码错误');
return false;
}
}
}

view文件:password.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;

/* @var $this yii\web\View */
/* @var $model backend\models\User */

$this->title = '修改密码';
$this->params['breadcrumbs'][] = ['label' => 'Adminusers', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
Yii::$app->session->getFlash('error');
Yii::$app->session->getFlash('success');
?>
<div class="user-updatepwd">
<div class="row" >
<div class="col-md-4 col-md-offset-4">
<div class="panel-heading">
</div>
<div class="panel-body">
<!-- <div class="col-lg-5"> -->
<?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>
<?= $form->field($model, 'oldpwd')->label('原密码:',['style'=>['float'=>'left','margin-top'=>'10px']])->passwordInput(['placeholder'=>'请输入原密码']) ?>
<?= $form->field($model, 'newpwd')->label('新密码:',['style'=>['float'=>'left','margin-top'=>'10px']])->passwordInput(['placeholder'=>'请输入6~18位英文字母、数字']) ?>
<div class="form-group">
<?= Html::submitButton('确认', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>
</div>
</div>

</div>

controller文件中添加函数actionPassword()

1
2
3
4
5
6
7
8
9
10
public function actionPassword(){
$model=new PasswordForm();
$request = YII::$app->request;

if($request->isPost && $model->load(Yii::$app->request->post()) && $model->changePassword()){
return $this->redirect('index');
}else{
return $this->render('password',['model'=>$model]);
}
}

显示PDF

将pdf或含该pdf的文件夹(personal/作业1(1711436_皮春莹).pdf)放到web目录下,在视图文件中加按钮,url为:

1
'url' => ['/personal/作业1(1711436_皮春莹).pdf']

点进去之后就跳到pdf,然后点回退按钮可以回到原来的界面

下载压缩包

同上,url为:

1
'url' => ['/personal/作业2(1711436_皮春莹).rar']

点击后直接开始下载

PHP中显示日期的date()函数

显示年月日:date(‘Y-m-d’);

年月日时分秒:date(‘Y-m-d H:i:s’)

python编程基础

  • 搭建编程环境

  1. 下载python:下载网址:https://www.python.org/downloads/windows/,选择python3的版本,选择python的可执行文件安装包
  2. 安装python:python3.6已经可以自动添加环境变量,python2需要手动配置环境变量
  3. pycharm的安装与配置:下载网址:http://www.jetbrains.com/pycharm/,下载社区版
  • python基础知识

  1. 变量和类型、变量命名、运算符
  2. If…elif…else
  3. for-in循环
  4. 函数及参数 :def 关键字 、参数默认值 、可变参数
  5. 变量作⽤用域 : 局部作⽤用域、嵌套作⽤用域 、全局作⽤用域
  6. 字符串及常⽤用⽅方法
  7. 常⽤用数据结构:列表 list(可重复,数组 ) 、元组 tuple(值不能被修改 ) 、集合 set(值不重复 ) 、字典 dict(键值对,类似map)
  8. ⾯向对象编程: 定义类、继承(子类继承父类的属性+方法)
  9. 文件读取: 文件的打开⽅方式、捕获异常,增强健壮性

爬虫的基本技术

  • 定义:是按照一定的规则自动浏览万维网并获取信息的机器人程序
  • 分类 :通用网络爬虫( 从一个种子URL扩充到整个—— 深度/广度优先策略 )、聚焦网络爬虫、增量式网络爬虫 、Deep Web爬虫
  • 工作流程:
  1. ​ 设定抓取目标(种子页面/起始页面)并获取网页。
  2. ​ 当服务器无法访问时,按照指定的重试次数尝试重新下载页面。
  3. ​ 在需要的时候设置用户代理或隐藏真实IP,否则可能无法访问页面。
  4. ​ 对获取的页面进行必要的解码操作然后抓取出需要的信息。
  5. ​ 在获取的页面中通过某种方式(如正则表达式)抽取出页面中的链接信息。
  6. ​ 对链接进行进一步的处理(获取页面并重复上面的动作)。
  7. ​ 将有用的信息进行持久化以备后续的处理
  • 工作原理:

Robots.txt文件中说明user-agent以及可以访问或不能访问的内容

  • 爬虫设计:
  1. 下载网页:urllib.requests
  2. 解析网页:BeautifulSoup
  3. 模拟交互,处理JS动态网页Selenium
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from urllib.parse import urljoin
import re
import requests
from bs4 import BeautifulSoup

headers = {'user-agent': 'Baiduspider'}
base_url = 'https://www.zhihu.com/'
seed_url = urljoin(base_url, 'explore')
l1 = [0, 0, 0, 0]


def spider(url, c):
link_set = []
titles = []
link_set.append(url)
print('Begin!')
dfs(url, 1, c, link_set, titles)
print('End, 共爬取了%d个页面!' % len(link_set))
return titles, link_set


def dfs(url, k, c, links, titles):
resp = requests.get(url, headers=headers)
soup = BeautifulSoup(resp.text, 'lxml')
href_regex = re.compile(r'^/question')
titles.append(soup.title.string)
if k == c:
return
for a_tag in soup.find_all('a', {'href': href_regex}):
href = a_tag.attrs['href']
full_url = urljoin(base_url, href)
if full_url in links:
continue
else:
links.append(full_url)
l1[k - 1] = l1[k - 1] + 1
dfs(full_url, k + 1, c, links, titles)


titles, links = spider(seed_url, 4)
f = open('test.txt', 'w') # 若是'wb'就表示写二进制文件
for i in range(len(titles)):
# print(links[i], titles[i])
s = str(links[i]) + str(titles[i]) + '\n'
f.write(s)
for x in l1:
f.write(str(x) + '\n')
f.close()

高级爬虫框架SCRAPY

规则

  1. name: 必须

  2. start_url、start_requests至少 一个存在

  3. 运行:scrapy runspider quotes_spider.py -o quotes.json

  4. parse: 默认回调函数

重要概念:css选择器、 yield关键字

response.follow

  1. 支持相对URL,无需调用URLJOIN
  2. 支持选择器
  3. 支持html标签

主要命令

查看帮助:

scrapy -h

创建项目:

scrapy startproject -h

scrapy startproject tutorial

运行:

scrapy crawl -h

scrapy crawl quotes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import scrapy


# class QuoteSpider(scrapy.Spider):
# name = 'quotes'
# start_urls = [
# 'http://quotes.toscrape.com/tag/humor/',
# ]
#
# def parse(self, response):
# for quote in response.css('div.quote'):
# yield {
# 'text': quote.css('span.text::text').get(),
# 'author': quote.xpath('span/small/text()').get(),
# }
# next_page = response.css('li.next a::attr("href")').get()
# if next_page is not None:
# yield response.follow(next_page, self.parse)

class QuoteSpider(scrapy.Spider):
name = "quotes"

def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)

def parse(self, response):
page = response.url.split("/")[-2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb')as f:
f.write(response.body)
self.log('Save file %s' % filename)

使用git下面的命令时

1
git checkout master

报错:

1
pathspec 'master' did not match any file(s) known to git.

解决过程:

  1. 查看分支情况(git branch -a)
  2. 没有看到master的分支,则需要先获取所有分支(git fetch)
  3. 切换到远程master分支(git checkout origin/master)
  4. 从当前的detached分支切换并新建分支(git checkout -b master)
  5. 建立本地分支和远程分支的追踪关系(git branch -u origin/master master)
  6. git pull得到反馈:Already up-to-date.

yii2初始化: init,开发环境:0,yes

Yii2 初始化的主要工作是产生一些配置文件和脚本文件,使用 GitHub 作为代码版本库,这些配置和脚本文件默认是被忽略提交的

根目录下的 /vendor 是第三方代码库(包括Yii2源码等),默认情况下是忽略提交的,由 Composer 维护。

但由于 Composer 在中国被墙速度慢,所以此推荐将 /vendor 也加入版本库,具体操作:注释掉根目录下 /.gitignore 文件里的 /vendor 内容。

使用gii


yii2安装后台adminlet模板报错: ‘dmstr\web\AdminLteAsset’不存在

1
到项目的advenced目录下,在安装后台模板框架执行命令: composer require dmstr/yii2-adminlte-asset "2.*"

后台主题安装成功后,将主题配置到yii中去:copy项目vendor/dmstr/yii2-adminlte-asset/example-views/yiisoft/yii2-app下的layouts和site拷贝到backend/views下面,将默认的layouts和site替换覆盖即可.

Seems you have downgraded Yii Framework from version 2.0.16.1 to 2.0.11.


Fatal error: Cannot use ‘Object’ as class name as it is reserved in E:\Xampp\htdocs\yii2\Centenary\vendor\yiisoft\yii2\base\Object.php on line 77

.\vendor\yiisoft\yii2\base\Object.php:

* Object is the base class that implements the property feature. It has been replaced by [[BaseObject]] in version 2.0.13 because object has become a reserved word which can not be used as class name in PHP 7.2.


不能登录进入index时:

SiteController.php中behaviors():access的action中role由@改为?

@表示已登录用户,?表示游客


backend\config\main.php

1
2
3
4
'user' => [
'identityClass' => 'common\models\Adminuser',
...
]

Uncaught Error: Using $this when not in object context in ……

解决:在backend\views\layouts\left.php中:[‘label’ => ‘留言管理’, ‘icon’ => ‘ fa-database’, ‘url’ => [‘/message/index’]],


模板放进yii2框架

asset文件夹

yii框架改三个地方:/assets/AppAsset.php资源目录文件(header照抄css,script中照抄js),/web/资源目录(),/views/layout页面布局文件(嵌入模板\<?= \$content>呈现子页面)

HTML代码改成PHP代码后可引入文件

actionIndex中指出使用哪个页面:$this->layout=” “

controller/access:页面是否可达

json数据交换格式

composer.update自动升级,解决由依赖导致的冲突

插件https://packagist.org/?query=select2

maven在java中组件管理

修改基类:添加BaseController,使之继承Controller,作为一个中间类,不要修改源码


命名规范:

view:全为小写,不同的单词用横线分隔

model与controller:开头字母小写,不同单词首字母大写


占位符,内置机理,防止sql注入

csrf:f12 “Form Data”中_csrf防止csrf攻击,模仿站点

客户端(浏览器)————服务器(yii框架PHP…)

  1. 请求资源(服务器生成csrf并传递给客户端) 2. 服务器返回资源(返回登录页,加密的csrf,cookie) 3. 客户端提交信息 4. 服务器返回信息的结果(服务器比较csrf是否一样)

f12 application storage

xss:蠕虫攻击


在yii2中使用echarts:1. 以插件引入 2. 以js引入(https://echarts.baidu.com/echarts2/doc/start.html)

题目描述:判断回文数字

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
不用将数字转成字符串,而是在数字长度一半的地方,将右半部分反转,与左半部分进行比较
若相等,则为回文数字;否则不是。
判断一般的位置:左边的数字不大于右边的数字
*/
bool isPalindrome(int x)
{
if (x < 0) return false;
if (x < 10)return true;
int left = x, right = 0;
if (!(left % 10))return false;//末尾是0的情况
while (left > right){
right = right * 10 + (left % 10);
left /= 10;
if ((left / 10) > 0 && (left / 10) <= right)
break;
}
if (left == right|| (left / 10) == right)return true;
return false;
}