普通视图

发现新文章,点击刷新页面。
昨天以前首页

尝试升级 WordPress 版本 和 PHP 版本,然后失败了

作者 石樱灯笼
2024年10月25日 23:36

尝试把 WordPress 从 5.2 版本 升级到 6.6 版本,把 PHP 从 7.4 版本升级到 8.3 版本。

任务艰巨得完成不了。

非常的崩溃。


前提

我现在的线上的博客,以及线下的开发环境,以及(如果还在不为我知的某个角落存在的话)商用用环境,都是 PHP 7.4 的。

最早些时候,应该算是2015年,正式入坑 PHP ,那时候基本是公司用啥,我用啥。PHP 5.2 5.4 5.6 都用过了,尤其是 5.2 大坑一大堆,摔过很多次。然后到 2016 年的时候终于用上了革新的版本 PHP 7.0。真爽。再后来开始自己独立开发环境,直接开了 DAMP 的坑,最初也是用的 7.0 版本,然后就很随意的升到 7.3 版本,主要是当时开发负担少。然后博客站也都升级到了 PHP 7.3。

再后来 2021 年接了一个外包项目。虽然当时 PHP 8.0 已经发布了,但是貌似周边支持都不怎么地。为了保证开发速度,直接用了 PHP 7.4 版本。当时还涉及到前端开发,Node环境也是大更新,很早之前一直用的各种热门前端库基本都死绝了。博客和本地开发环境也都升级到了 PHP 7.4,博客的 WordPress 程序倒是没变,还是 5.2 版本(这里埋了个大坑),只是偶尔会从官网下载代码包然后手动更新对应的文件,以修复些潜在的安全问题。

现在是2024年年末,就连PHP 8.0 都已经停止维护快满一年了,最新版本 PHP 8.3 也已经发布快满一年了。WordPress 都到了 6.6 版本了,一堆 WordPress 插件都已经停止 5.2 版本的支持了。

想趁着有时间有机会,把 PHP 和 WordPress 都升级了。

天真了。


第一天

首先是把线上的代码全备份一遍。这个毫无工作量,我之前写了个备份代码,直接就把自己的整站扒下来。然后把备份的站再部署到本地的开发环境上,再改几个数据库字段,就完事了。打开后台,先禁用所有插件,以便升级之需。

Apache2 和 MySQL 不用动,因为用的一直都是 Docker 的最新版本,这几年也没什么巨大的兼容性变化。

PHP 这块我不知道算不算麻烦。我把 PHP 从 7.4 到 8.3 的所有 不向后兼容变更废弃功能 全都看了一遍。没多少,就几页,几分钟就看完了。个人感觉这么多变更,只有一条能实际影响到我日常开发工作,就是自 8.0 起不再支持 带有默认值的参数后面跟着一个必要的参数

screenshot_on_b85m_by_flameshot_at_2024-10-24_22-51-45.png

其实个人工作中也很少这么用,因为易读性有点烂。论性能来讲的话这么写性能也很差,只不过以前工作过的公司里就有很多人这么写,主要是为了防止其他同事调用函数忘记传参(空参也是参)。

其余的改动基本影响不到我。我使用的基本都是 PHP 的官方建议用法,最多也就是会遇到某些外部库被遗弃然后有个平替的情况,比如数据库接口啥的,即使出错了立刻就能发现。

于是很自信的先把 PHP 环境升级到了 8.3 。因为是基于 Docker 的所以也完全不用担心环境污染的问题。

然后就崩了,WordPress 就打不开了。

这倒是意料之中,毕竟当年 WordPress 4.3 版本当年连 PHP 7.0 都不支持。我现在用的是 5.2 版本,最高能支持的 PHP 版本也才 7.3 ……

Screenshot_2024-10-24_at_23-02-46.png

什么?7.3?但我已经用 PHP 7.4 跑了 WordPress 满 3 年了啊???

什么兼容性测试……

下载了个 wordpress-6.6.2 的包,按官方文档手动安装。 崩得一塌糊涂

全部删除了重新来,这回用官方的自动升级功能,直接从 5.2 升级 6.6。真神奇,WordPress 官网被墙了这么久了竟然能秒下 WordPress 的安装包,我也不知道他是走的什么渠道。PHP 就这点恶心,前台所有操作你都看不到任何细节,就像是在用 Windows 一样。

成功安装。然后 崩得一塌糊涂 。这回不仅崩得稀烂,而且由于没手工删除后台的旧文件,新旧文件混在一起,更是手足无措。

就这么搞了超过6个小时,一直干到后半夜三点多,搞不定。

放弃,睡觉。

然后严重失眠,抽搐。

screen_IMG_2148.png


第二天 白天

首先考虑下到底是 PHP 的问题还是 WordPress 的问题。

按理来讲我已经把 PHP 的升级文档都看完了,并没有什么会天塌一般的变更,但是 WordPress 这边的确天塌了。

先在 PHP 8.3 环境下运行一下我的其他项目看看,结果我的个人主页就崩了。

screenshot_on_b85m_by_flameshot_at_2024-10-24_23-33-27.png

我用的是 2023 年 3.1.48 版本 的 Smarty,其基础版本是给 PHP 7.0 做的,可能旧了吧。

下载了最新版本的 smarty-5.4.1 ,然后

screenshot_on_b85m_by_flameshot_at_2024-10-24_15-36-49.png

什么玩意? implode is Deprecated ,我怎么不知道?

又去重新看了一遍 PHP.net 官网的 implode 文档和 PHP 升级文档。根本没有 Deprecated 。

然后在网上搜了一下,发现是 Smarty 的锅。而且 Smarty 还在 join 和 implode 之间反复横跳。更恶心的是,implode 和 join 在 PHP 7.4/8.0 中已经声明并废弃了 先数组后分隔符 的用法,但是在 Smarty 中却是强制要求 先数组后分隔符 ?甚至官方在 issue 里来来了句 Smarty is Smarty and PHP is PHP. 有病吧。而且你就算有病,你特么连个文档都没有,谁知道你有这种抽风的设计啊。

你要知道之所以我还用 Smarty 这种超级古董,就是因为这是一种 靠谱的、前后端分离、完全后端渲染、仅需要 HTTP 和 PHP 环境、不需要臃肿框架和特定语法,的网页渲染模式,是提供给搜索引擎最靠谱的传统模式。没有网页模板系统的话,想写这种纯后端渲染前端显示的页面,就只能 php 和 html 代码混写,非常的恶心。

现在 Smarty 抽风了,真就不知道以后还怎么不依赖框架写这种页面。我搜了下,Laravel 的 Blade ,和 Symfony 框架下的 Twig,貌似也可以独立使用,但是我对 Laravel 和 Symfony 基本一无所知,作为一个 PHP 开发者真是有点丢人。

话题扯远了,回到刚才。

我目前是不太想动我的个人主页的,这 WordPress 是大头,是主要内容。主页只是个入口。虽然主页改动起来并不困难,代码量少,Smarty 抽风的部分比较好找。但主页这一块我其实并不满意,主要是多语言这块用的传参而不是独立页面,很受搜索引擎嫌弃,基本上没收录,收录的也搜不到。但我的确没有精力和欲望去重做。

另一方面,WordPress这边,崩溃得最多的部分其实是插件。WordPress的代码质量本来就很堪忧了,第三方插件更是三脚猫,各种天花乱坠的不规范语法,可以说基本上都不能在 PHP 8.3 上运行。

另外我虽然看了 不向后兼容变更废弃功能 ,但是 PHP 新版新增的语法糖也有点天花乱坠。我用的是最新版的 php-cs-fixer_v3.64.0 ,没配置好的话就会把那些插件的奇葩写法转写成 8.3 的语法糖,有时结果更是瞎眼,基本没有易读性。

综上考虑,先放弃 PHP 8.3 的升级。先把能通的条通。PHP 的升级难度应该不是最高的,但是底下这些撇不掉的小垃圾目前是必须要保且支持不到 PHP 8.3,没精力做修改。

放弃 PHP 8.3 继续用 PHP 7.4 。


第二天 晚上

看兼容性列表,WordPress 6.6 也是支持 PHP 7.4 的。

但是实际上 API 改动实在太大了,而 PHP 前端应用最恶心的一点,就是 出错了,不报错

即使开启了 define('WP_DEBUG', true); define( 'WP_DEBUG_LOG', true ); define( 'SAVEQUERIES', true ); ,也经常是

  • 功能好像开了但是没开
  • 功能好像崩了但是啥日志都没有
  • 功能正常使用但是页面上打了一堆不知道哪里来的错误日志

面对如此大的一个工程而大部分代码逻辑都是不可靠的。升级到 6.6 实在是消受不起。

放弃 WordPress 6.6 ,只升级到比较近的版本。

要不然试试 5.5 吧,毕竟我在用的一款插件,作者自评最高支持到 5.5。

下了个 WordPress 5.5 的安装包,装完了。崩,但是崩得没有 6.6 多。

主题 graphene

不开插件,只看主题,首先就是文章的评论显示不出来。检查后发现是评论的API变了,而我的主题 graphene 是 1.9.4.3 版本的,不支持 5.5 。

screenshot_on_b85m_by_flameshot_at_2024-10-25_00-48-04.png

有时候看其他人的代码就是折磨,代码里写法五花八门,空格TAB混着,一会拼接字符串,一会替换字符串。单引号双引号混着用,左边括号有空格,右边括号换行了。

说实话我都不知道这算不算改好了,反正现在是能显示出来。我更担心的是其实还有哪个不知道的角落还有错,但是看不到,毕竟 PHP 前端 出错了 不报错

官方倒是有个新版的 graphene,但是我现在用的这个主题就是我大量改动过的,因为 graphene 原版的代码实在是, 太错了 。好多代码完全不符合前端的理念。然后是颜色和界面也是要一点一点从设置里调,那复杂和麻烦程度,说真的我更乐意重写 HTML 和 CSS 。

我真的想过很多次自己做一个 WordPress 主题,这个想法可是足够老了。但是当时 WordPress 3 版本的主题文档就恶心到我了,真的超级麻烦。而到如今就 WordPress 现在的代码质量,我估计开发主题会更困难更恶心。

也是怪不得其他更轻量的博客程序能后追直上。

插件 Disable WordPress Core Updates

接下来是 Disable WordPress Core Updates 这个插件。

这个插件是为了禁用 WordPress 的界面更新的。但是其实只有一行有意义的代码:

add_filter( 'pre_site_transient_update_core', create_function( '$a', "return null;" ) );

首先 create_function 这个函数在 PHP 7.2 废弃,在 8.0 中删除,所以我改写成了。

add_filter('pre_site_transient_update_core', function ($a) { return null; });

然后就见证奇迹了。能用是能用,但是 pre_site_transient_update_core 这个字段我在整个 WordPress 代码中都没找到。为什么做一个 pre_site_transient_update_core add_filter 就能抑制 WordPress 界面提示升级? 魔法啊?

然后开启这个插件的时候,更新页面是崩的。

screenshot_on_b85m_by_flameshot_at_2024-10-24_21-14-55.png

魔法。

插件 NIX Gravatar Cache

接下来是 NIX Gravatar Cache 插件。

这是个把 Gravatar 头像缓存到本地服务器的插件,只不过早就死透了。我当时随便改了点代码对付着用,大部分时间没出错也就那样了。

首先是这段代码。(红色部分是我添加的改动)

screenshot_on_b85m_by_flameshot_at_2024-10-25_01-04-29.png

不能直接执行 wp_enqueue_scriptwp_enqueue_style ,要先执行个 add_action('wp_enqueue_scripts', 引用能调用那俩玩意的函数); 。外国人看这种超长的单词时不会眼花吗?

然后是这么一段代码。

screenshot_on_b85m_by_flameshot_at_2024-10-25_01-00-47.png

WordPress 的 register_啥啥啥_hook(__FILE__, array($this, '函数名')); 写法全都作废了,要改成 register_啥啥啥_hook(__FILE__, array($this, '函数名'));

接下来底下那一节:

  • 假如 路径不可写 且 路径为目录,报错

否则

  • 假如 创建目录(权限777)失败 且 路径不为目录,报错

就这烂判断条件看得我脑子都快炸了也没弄明白为什么这破玩意能在我线上服务器上跑几年没报错,而我本地开发环境却根本跑不通。

screenshot_on_b85m_by_flameshot_at_2024-10-25_01-19-42.png

而且这玩意讨厌就讨厌在于,确在我的测试环境下报错了,但是 WordPress 只是多了个 .php-error 的样式并且高出来 2em 的一节,但是一点错误日志都没有!!! 出错了 不报错

最后还是靠自己写 debug 代码定位的问题。

这 TM 都是些不该是问题的问题,竟然多得到处都是。

2天,一点有效进展都没有。唯一有效收获就是这些屎山不碰就没事,一碰能崩得全身是屎。

反而自己写的没有引用那些垃圾玩意的插件和程序,没发现啥大毛病。


第三天

2天没啥进展,给我干懵了。

俗话说没事别升级,升级必出事。

原本的想法是先试着升级,如果不能平滑升级的话,大不了全摧毁了,然后把整个博客文章用导入的方法塞回去重建。如果插件出问题了,大不了找找看是否有新的替代品。结果搜了一下,靠谱的插件基本没有,一大堆商业推广的插件,和一大堆复合性插件,而且这些插件无论对 5.x 版本 还是 6.x 版本的兼容性都乱七八糟,问题解决不了,还有可能引入更多的问题。主题这边则是更不想换,一方面本身现在用的主题就是我大量修改过的,因为网上的各种主题,仅安全性就一塌糊涂,更别说 HTML 标准了。我这主题还是专门针对 1366×768 分辨率优化过的,能在 小屏幕 150% 比例正常显示。让我再去改个新的,工作量也是太大。

现在基本上没辙了。

PHP 这边其实还行,而且版本活跃度比较稳定。

screenshot_on_b85m_by_flameshot_at_2024-10-25_22-09-00.png

https://packagist.org/php-statistics 能看出各版本使用占比都跟维护相关。但 7.4 版本 比 8.0 版本还受欢迎 属实乐了。

但是周边应用真的是质量山体滑坡。WordPress自 3.0 版本就开始崩,后面很多发展都很魔幻,就连编辑器都是靠社区兜底,到现在已经想不清楚这玩意的产品路线是啥了。

其他生态我也不清楚,毕竟作为一个 PHP 开发,我连 Laravel 和 Symfony 都没用过,商用产品都是用 ThinkPHP 应付的,当然最爽不过不依赖框架没有条条框框自己从头写。

但是像 Smarty 这种原行业标志都走奇葩路线了。可以说整个IT行业,基本上,正常的元老人物都退出舞台了,剩下的这些,刨去臭鱼烂虾,就只有偏执而扭曲了,假若走向歪路,那就没得旧,而这一点在开源社区上也极为明显(因为闭源商业的死不死没人关心),Godot 基金会开搞政治正确炮轰特朗普和动画头像用户,Linux 基金会直接开踢俄罗斯的代码贡献者。IT 行业现在就像是一个患了早期癌症的癌细胞轻微扩散病人,看似有救但却是谁都不想救。


结论

给我干哑火了,懵逼了,现在不知道咋整了。

The post 尝试升级 WordPress 版本 和 PHP 版本,然后失败了 first appeared on 石樱灯笼博客.

Puock主题修改备忘录

作者 陈大猫
2024年10月16日 16:05

作为一个写博十余年的老博主,实在是没有精力折腾各种新东西。但近期博客程序被入侵事件让我不得不换掉了使用很久的Flat主题。

本来想在后台随便找个官方推荐的主题凑合用,但那些主题基本上都是歪果人设计的,对中文排版支持不太友好,所以又重新找了款国人开发的主题,也就是本站正在用的——Puock主题

这款主题美观大方,功能强大,一次性解决了我很多痛点。可以说是立即部署、立即使用。

但使用了几天后,还是发现有需要调整的地方。现在记录一下,免得后面忘记了。

一、评论者URL跳转问题

主题模板设计的功能是:评论者如果留了URL的,则进行base64加密,然后通过一个中转页面进行二次确认,再进行跳转。

我对这个功能的态度是:完全不需要。

博友互访留下URL,并且清晰地展示在前台,我认为是非常重要的,加密再跳转极其影响用户体验。对于那些发广告的评论,我是一律删除就完事了,所以并没有这个需求。关键是,经过测试,部分URL加密后无法正常跳转,而是会跳到我博客首页,这完全让人摸不着头脑。

由于本人对代码几乎一窍不通,看了半天也没找到哪里能关掉这个功能。

开始把go.php里的代码丢给“文心一言”去分析,并根据AI指引修改里面的代码,试图取消加密,直接调转,但无果。

之后采取笨方法,直接用全文搜索,搜出了包含“go.php”这个关键词的页面opt.php,路径位于:

主题模板文件夹下的 /inc/fun/opt.php

相关代码为:

//跳转链接

function pk_go_link($url, $name = ”)

{if (pk_is_cur_site($url)) {

return $url;

}$url = PUOCK_ABS_URI . ‘/inc/go.php?to=’ . base64_encode($url);

if (!empty($name)) {

$url .= ‘&name=’ . base64_encode($name);

}return $url;

}

这段代码丢给AI,让他改为不加密,但AI弄了半天,不成功。

我看了下代码,还是采用最笨的方法,将$url =后面的内容改为了$url,也就是左右相等,替换后如下:

//跳转链接

function pk_go_link($url, $name = ”)

{if (pk_is_cur_site($url)) {

return $url;

}$url = $url;

if (!empty($name)) {

$url .= ‘&name=’ . base64_encode($name);

}return $url;

}

再次刷新运行,完美解决。

二、屏蔽键盘左右键翻页功能

这个问题是博友S发现的。

在单篇文章页面,使用键盘左右键可以实现上一篇、下一篇的快速切换。

看起来很美好,但这里有个“致命”BUG,当浏览者在评论框里输入文字时,不小心使用了键盘左右键来调整内容,此时页面会马上切换到上一篇或下一篇,直接导致整个评论表单输入的内容全部丢失。

当我打算去官方开发者博客留言反馈这个问题时,结果光是写那条留言就反复写了五六次——官方竟然复刻了这个问题,也就是说跟我博客运行环境是没有关系的。

在等待官方修复这个BUG之前,我尝试自救。

跟文心一言沟通多次,并没有给出有效的解决办法。

无奈之下,找到了chatgpt,让他给我写一个屏蔽键盘左右键的插件,修改一次后,解决问题。

现在,我的博客将暂时屏蔽键盘左右键,按下时会弹出对话框,虽然也有一定影响,但总比吞掉辛辛苦苦敲下的文字强吧。

10.18更新:

在GitHub提交issue后,网友hausen1012回复说遇到同样问题,并给出了相关的代码。

经测试,删除主题模板下/assets/dist/js路径中puock.min.js文件以下代码即可取消左右键翻页功能:


{
key: "keyUpHandle",
value: function() {
var a = $(".single-next-or-pre");
a && (window.onkeyup = function(t) {
var e = null;
switch (t.key) {
case "ArrowLeft":
e = a.find("a[rel='prev']").attr("href");
break;
case "ArrowRight":
e = a.find("a[rel='next']").attr("href")
}
e && (window.location = e)
}
)
}
}

10.22更新:

感谢博友老何提醒,由于直接删除上述代码,会导致评论回复功能不可用(我猜是keyUpHandle这个功能还关联了其他事件)

忍不住又折腾了一下,经过chatgpt的分析,把上述代码修改为下面的代码:


{
key: "keyUpHandle",
value: function() {
var a = $(".single-next-or-pre");
var commentBox = $("#comment"); // 获取评论框

// 定义事件处理函数
var handleKeyUp = function(t) {
var e = null;
switch (t.key) {
case “ArrowLeft”:
e = a.find(“a[rel=’prev’]”).attr(“href”);
break;
case “ArrowRight”:
e = a.find(“a[rel=’next’]”).attr(“href”);
}
e && (window.location = e);
};

// 绑定事件
if (a.length) {
window.addEventListener(“keyup”, handleKeyUp);
}

// 解绑事件的函数
this.unbindKeyUp = function() {
window.removeEventListener(“keyup”, handleKeyUp);
};

// 监测评论框的焦点事件
commentBox.on(“focus”, () => {
this.unbindKeyUp(); // 当焦点在评论框上时,解绑键盘事件
});

// 可选:在评论框失去焦点时重新绑定事件
commentBox.on(“blur”, () => {
if (a.length) {
window.addEventListener(“keyup”, handleKeyUp); // 重新绑定事件
}
});
}
}

希望不会再衍生出新的BUG。

迭代幂运算/重幂的介绍与其Python代码实现


数学中的迭代幂运算/重幂是什么?

迭代幂运算(重幂)是数学中的一种运算,涉及到反复进行幂次运算。它是超运算序列的一部分,该序列延伸了加法、乘法和幂运算。在迭代幂运算中,一个数自乘多次,直到达到指定的次数。

一个数a迭代幂的高度n通常表示为:tex_7f275feba9caa33491cc739d97613e41 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 ,也就是把n写在a的左上角,(也可以记作:a↑↑n)这表示a被迭代n次。

例如:

  • tex_809d19495ee2ad967edb956694773d96 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 (简单恒等式)
  • tex_b2971689df7256a7c315e159e8dceca6 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 (a自乘一次)
  • tex_185fcc3b7fe6daf47068d87ffd22f670 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 (a的幂次为a自乘)
  • tex_a932b7bb96225dc665bbe571f816002a 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 ,依此类推。

在迭代幂运算的上下文中,tex_b3ef97b6eba2428ee919c02c89d2c9ea 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 通常未定义或没有普遍共识。然而,一些数学惯例建议对于任何 tex_58c6653dfed174ea991f702adfb3e6f4 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 tex_2f1f5ed0eeff6d95cf9b145624dfb6af 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 ,类似于在幂运算中对任何非零的 tex_58c6653dfed174ea991f702adfb3e6f4 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 tex_5c135adeedf02dca7953a9719fb38fa2 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 的情况。

迭代幂运算示例

让我们评估 tex_a5f6729c6edbc3df5dae3c81efe128b2 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 (读作“2迭代到高度3”):

tex_c3974a6b51c4029486462ba28d7f5c17 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机
tex_38f3272f3cc8a02e84ceed576663756c 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机
因此 tex_a79a23ebbcc28f19e40a7b5604f3e748 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机

迭代幂/重幂运算的通用性质

  • 非交换性:迭代幂运算不是交换的,这意味着 tex_2bb7d37b96ba358da2a2c8024d02fe57 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机
  • 增长速度非常快:迭代幂运算增长非常快。即使是小数也会因为幂运算的快速增长而导致非常大的结果。

迭代幂运算/重幂在基础数学中较少见,但在某些高级数学领域中发挥作用,特别是在涉及极大数的领域,如大数理论和计算机科学中。

用 Python 计算迭代幂运算

以下是两个计算迭代幂运算的Python函数。第一个使用递归,第二个使用迭代。

在两个函数中,我们在开始时添加了对 n = 0 的检查。如果 n 为 0,则函数返回 1,否则继续处理。这种方式使函数能够按照任意数的迭代幂高为0时为1的惯例处理 n=0 的情况。

递归函数计算迭代幂

递归函数:此函数将自己调用,n 的高度递减1,直到达到1,此时返回基数a。这就实现了从上到下构建指数链的效果。

@lru.cache(None)  ## 缓存函数
def tetration_recursive(a, n):
    if n == 0:
        return 1
    if n == 1:
        return a
    return a ** tetration_recursive(a, n - 1)

递归计算迭代幂的函数理论上可以进行尾优化。在尾递归中,递归调用是函数中的最后一个操作,这样某些编译器或解释器可以通过重用相同的堆栈帧来优化调用堆栈的使用。这可以通过消除每个递归调用的额外堆栈帧需求来将空间复杂度降到 O(1)。

然而,当前的递归实现并不是尾递归的,因为递归调用嵌套在一个幂运算中:

return a ** tetration_recursive(a, n - 1)

这里,幂运算依赖于递归调用的结果,所以在完成当前调用之前必须计算出结果,从而阻止了尾递归优化。

迭代函数计算迭代幂

迭代函数:此函数使用 for 循环遍历高度 n,通过在每次迭代中更新幂运算的结果,来从下至上计算结果。

def tetration_iterative(a, n):
    if n == 0:
        return 1
    result = a
    for _ in range(1, n):
        result = a ** result
    return result

迭代幂算法的时间/空间复杂度

Python函数计算迭代幂的时间和空间复杂度取决于其递归或迭代实现。让我们分析两种实现。

递归函数的复杂度

时间复杂度:

  • 每次递归调用都会与之前的调用结果进行一次幂运算。
  • 总共有n-1次递归调用,所以该函数被调用了O(n)次。
  • 然而,像 tex_ad68cb15ab4e6c9d3aa23d421625d67a 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 的幂运算需要 tex_e6c0128be5c7d7501ff5a45664d688da 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 的时间。
  • 因此,对于较大的 n 值,由于幂次的增长,其时间复杂度会呈指数增长。
  • 这导致总的时间复杂度大约为 tex_61a94ff4b35f50421447e762bcc2b21e 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 ,有n层,这意味着增长速度非常快

空间复杂度:

  • 由于这是一个递归函数,每次调用都需要堆栈空间。
  • 递归的最大深度为 n,所以空间复杂度为 O(n)。
迭代函数的复杂度

时间复杂度:

  • 与递归版本一样,该函数迭代 n – 1 次
  • 每次迭代涉及计算 tex_58c6653dfed174ea991f702adfb3e6f4 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 的幂次,这个结果会呈指数增长。
  • 因此,时间复杂度也成为 tex_61a94ff4b35f50421447e762bcc2b21e 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机 ,有n层,因为每一步都是指数级增长。

空间复杂度:

  • 此迭代版本仅需要少量额外空间用于 result 变量等,因此它的额外空间复杂度为 O(1)。
  • 然而,结果本身可能会变得非常大,如果 a 和 n 很大,可能需要大量内存来存储。

由于反复幂次的快速增长,这两种实现的时间复杂度都非常高,对于较大的值变得不可行。递归版本由于调用堆栈的使用空间复杂度为 O(n),而迭代版本的辅助空间复杂度为 O(1),但仍然需要处理极大数,这可能会间接影响内存使用。

英文:Tetration Operator in Math Simply Explained with Python Algorithms

本文一共 1253 个汉字, 你数一下对不对.
迭代幂运算/重幂的介绍与其Python代码实现. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 迭代幂运算/重幂的介绍与其Python代码实现 Python 学习笔记 数学 数学 程序设计 计算机
The post 迭代幂运算/重幂的介绍与其Python代码实现 first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  2. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  3. 英国房子的EPC节能报告(Energe/Efficiency Performance Certificate) EPC (Energe/Efficiency Performance Certificate) 是英国房子的节能报告, 法律上规定, 每个房子都必须要有一个EPC报告, 报告的有效期为十年. 房东在把房子出租或者想卖房的时候, 这个EPC就必须有效, 在一些情况下 比如出租房子的时候, 这个EPC报告还必须符合一些最低标准, 比如房子必须满足 F档(类似及格线)...
  4. 给孩子零花钱培养孩子正确的金钱观价值观 两个娃已经不知不觉7岁8岁了. 媳妇和我商量一下决定给孩子每人每周5英镑的零花钱(Pocket Money). 这样他们慢慢的就有自己的小积蓄备将来不时之需: 比如朋友聚会生日啥的需要准备礼物. 同时, 我们决定不再给孩子买零食(薯片啥的). 孩子一天好几餐, 晚上睡觉前还得吃零食, 我们就多买了很多水果面包, 健康的食物多吃一些总不是啥坏事. 孩子可以用这些零钱买自己想要的东西, 我们也不再过问. 孩子有自己的决定权. 第一周的时候,...
  5. 拔牙后的注意事项(图, 慎入) Care of Mouth after Extraction 昨天又拔了两颗牙, 初步定在5月4号装牙套. 这是牙医诊所给的术后注意事项: 拔完后需要等3-4小时麻醉失效后才能吃喝. 稍微流点血是很正常的. 但是请不要漱口吐出, 因为这会加速流血. 你只要轻轻的含着口水并咽下即可. 如果一直流血, 请拿着纱布(并不是纸巾)放在拔牙处20分钟. 24小时内请不要运动, 术后几小时内回家静静坐着. 12小时内不要吸烟, 喝酒或者喝热饮, 因为这会让伤口流血....
  6. 同一台服务器上多个WORDPRESS站点的一些设置可以移出去 我自从把所有网站都挪到一处VPS服务器上 就发现很多事情省事很多 可以同时管理多个网站 包括 WORDPRESS博客. 比如我有四个WORDPRESS博客 然后我就把通用的一些资料给移出去 移到 HTTP或者HTTPS都不能直接访问的文件夹里这样就更安全许多. 文件 wp-conn.php 存储了 相同的数据库资料. 1 2...
  7. ChatGPT-4 使用 Math Wolfram 插件解决数学脑筋急转弯问题 这篇文章, 我们看一个简单的数学问题(脑筋急转弯), 并用 Python 解决它. 我们看一下LLM(大型语言模型): ChatGPT3.5和ChatGPT4. 通过 ChatGPT-Plus 订阅(目前每月 20 美元 + VAT增值税), 我们可以启用...
  8. HPZ800服务器主板太老不支持超过2TB的大硬盘 我家里一直用的是HPZ800服务器, 很吵, 很老, 虽然这台服务器已经有十年之久(我在EBAY上买来用了五年多了), 但是即使放到今天, 这服务器速度依旧很快, 很稳定. 由于服务器用的是ECC较验内存, 所以基本上不重启关机. HPZ800主机有两个硬核CPU – 因特志强 X5650 – 每个CPU是12核....

WordPress & Typecho 极简主题 Dear v1.1.0

作者 Jeff
2024年9月22日 21:11

周末对 Dear 主题 WordPress & Typecho 版本都进行了小更新。主要增加独立的“搜索模板”,并对行距、次要字体等地方进行了小优化。

Dear 主题首页设置页面 id 后,会引用该页面的所有内容和样式,同学们可以对该页面尽情发挥想象力,以满足个性化需求。比如展示订阅地址、社交网站地址等等,也可以贴个封面图作为首页 Banner 等。如下图 Follow Me:WordPress & Typecho 极简主题 Dear v1.1.0-雅余

本次版本主要更新内容:

- 增加独立“搜索模板”
- CSS 样式移至 style.css 文件
- 首页默认显示8篇文章
- 部分样式优化

新版本请从主题发布页面获取 Github 链接:

WordPress 版本Typecho 版本

WordPress 版本 Text Only 和 Writing 主题错误修复

作者 Jeff
2024年9月7日 10:53

昨晚更新 Paper 主题的时候发现了一处拷贝错误,把旧主题的代码直接粘贴了,部分 PHP 版本没有提示错误,所以没发现。现已对 WordPress 版本 Text Only 和 Writing两个主题发新版本修复,可针对性更新。主要是 archives.php 和 search.php 两个模板文件。

详细可查看主题发布页:Text Only (WordPress)Writing (WordPress)

WordPress & Typecho 极简主题 Paper v1.1.0

作者 Jeff
2024年9月7日 00:32

Paper 这款纯文本的极简主题得到不少同学的喜爱,应部分同学的要求对主题进行了更新。主要增加独立的“搜索模板”,并对多处负空间进行调整,增加文字呼吸的空间。还修正了”文章归档“模板的一处错误,可针对性更新。

主要更新内容:

- 增加独立“搜索模板”
- 菜单及部分代码调整
- CSS 样式移至 style.css 文件
- 优化多处负空间距离
- 优化评论框样式
- 修复文章归档模板错误

新版本请从主题发布页面获取 Github 链接:

WordPress 版本Typecho 版本

Typecho 纯文本极简主题 Text Only v1.0.0 发布

作者 Jeff
2024年7月26日 23:58

应朋友们要求,制作了 Typecho 版本的 Text Only 主题,和 WordPress 版本样式上基本保持一致。使用愉快~

主题介绍如下:

Text Only 为纯文本极简主题,黑白配色,对程序极简优化,主题无 JS 和图片文件载入。

主题支持自定义背景、自定义菜单,保留搜索及评论功能;内置文章归档和搜索模板;已作中文字体优化,内置3种字体方案可选。

主题类型:极简 / 博客 / 纯文本 / 单栏 / 自适应 / 免费

提供 WordPress 版本Typecho 版本

主题免费开源,供学习交流,不提供售后支持。如有建议,欢迎评论留言,不喜勿喷。

主题可按授权方式继续随意改造,但望保留我的信息。感谢!

Typecho 纯文本极简主题 Text Only v1.0.0 发布-雅余

Typecho 纯文本极简主题 Text Only v1.0.0 发布-雅余

Typecho 纯文本极简主题 Text Only v1.0.0 发布-雅余

Typecho 纯文本极简主题 Text Only v1.0.0 发布-雅余

Typecho 纯文本极简主题 Text Only v1.0.0 发布-雅余

详细介绍和使用见主题两个版本的发布页面。

WordPress 纯文本极简主题:Text Only
Typecho 纯文本极简主题:Text Only

欢迎提供建议,以便继续完善。

WordPress & Typecho 极简主题 Writing v1.1.0

作者 Jeff
2024年7月21日 15:10

上个月收到 Github 上面一条 Issue,借周末时间对主题小改动了一下。毕竟不是全职运维,拖拖拉拉一个月才改。

主要更新内容:

- 增加独立“搜索模板”
- CSS 样式移至 style.css 文件
- 部分样式完善

新版本请从主题发布页面获取 Github 链接:

WordPress 版本Typecho 版本

-

小插曲:太不专业了,commit 的时候手一抖,把另外一个主题的文件给替换了,哈哈。

WordPress 纯文本极简主题 Text Only v1.0.0 发布

作者 Jeff
2024年7月8日 23:18

手痒,又发一款极简主题。这是一款初始化主题,仅提供最基础的页面展示,简洁的样式,简洁的代码,方便后期加工。提供两个页面模板,归档模板和独立搜索页面。较以前主题,对评论区进行了适当的美化。

主题介绍如下:

Text Only 为纯文本极简主题,黑白配色,对程序极简优化,主题无 JS 和图片文件载入。

主题支持自定义背景、自定义菜单,保留搜索及评论功能;内置文章归档和搜索模板;已作中文字体优化,内置3种字体方案可选。力求极简,对程序自带功能进行禁用,若对使用有影响,按需删除即可。

主题类型:极简 / 博客 / 纯文本 / 单栏 / 自适应 / 免费

目前仅提供 WordPress 版本。

主题免费开源,供学习交流,不提供售后支持。既然供学习交流,故也欢迎和我交流。如有建议,欢迎评论留言,不喜勿喷。

主题可按授权方式继续随意改造,但望保留我的信息。感谢!

WordPress 纯文本极简主题 Text Only v1.0.0 发布-雅余

WordPress 纯文本极简主题 Text Only v1.0.0 发布-雅余

WordPress 纯文本极简主题 Text Only v1.0.0 发布-雅余

WordPress 纯文本极简主题 Text Only v1.0.0 发布-雅余

WordPress 纯文本极简主题 Text Only v1.0.0 发布-雅余

详细介绍和使用见主题的发布页面。

WordPress 纯文本极简主题:Text Only

欢迎提供建议,以便继续完善。

Firefox Addon 踩坑指南

作者 7gugu
2024年6月26日 13:52

最近为了提高工作效率,给Firefox开发了一个切换whistle代理的插件(Addon),但是Firefox在manifestV3上有很多规范都与Chrome不相同,且中文互联网关于这方面的知识很少,所以在此总结了一些我遇到的坑点,希望可以帮助大家。

开发模板

Firefox虽然没有太多关于V3的教程,但是插件开发还不至于从0开始搭建框架,此处推荐一个React+TS的开发模板,通过这个开发模板,可以“快速”打包出Chrome和Firefox平台的插件。

https://github.com/aeksco/react-typescript-web-extension-starter

该附加组件无法安装,因为它有可能已损坏

Firefox官方虽然说可以Self-distribute,但是文档的描述有问题,没有给出正确打包XPI的方式。直接将产物压缩成zip后,将拓展名改成xpi,Firefox依旧是不能正确识别的。

正确的方法应该是,将产物压缩成zip后,提交到AMO签名,签名后Firefox浏览器就能安装了。

操作流程:

1.提交本地产物到AMO上,选择自托管(https://addons.mozilla.org/zh-CN/developers/addon/submit/distribution)

2.审核签名完成后将XPI下载至本地即可

background.service_worker is currently disabled

这是因为在manifestV3中,Firefox与Chrome针对后台程序的处理有差异导致的。其实Firefox也是能使用后台程序的,但是不能直接写成service_worker。直接用service_worker,Firefox将会报错。

正确的写法应该是使用”scripts”代替”service_worker”,Firefox的后台程序变成了background_script。

The extension ID is required in Manifest Version 3 and above

上传产物压缩包到AMO的时候,可能会遇到这个问题,这个是因为Firefox在mainfestV3及以上版本中要求增加一个插件ID号和最低版本限制导致的,需要在manifest.json中增加该字段才可以。

最低版本号可以参考你所用的浏览器API限制来决定,id一般使用<插件名>+@+<个人域名>就可以了(只要保证ID唯一即可)。

参考插件

之前在Blog中分享过一次这个调试插件,可以以这个插件为基准来检查自己的插件是否符合上架要求。

wordpress 获得当前文章真实序号的方法

作者 大致
2024年3月7日 21:43

想在主题里利用一下这个小功能。
那些抄来抄去的都包了浆的所谓办法都是在后续的ID上作文章,根本没有切中问题的本质。因为在wordpress的设计思想中,万物皆post,根本没把ID的增长当回事。想通过限制自动保持、自动版本、限制媒体什么的解决方案是缘木求鱼,根本不治本。
其实“取连续的文章序号”换个思路,就是取“截止当前发表时间,它的前面还有多少篇”这么一个简单问题。刚好wordpress的核心类WP_Query支持根据时间检索,而时间检索的参数里刚好有个’before’。一拍即合。
下面就是代码。注意:此代码要在loop内部使用。

get_real_post_id() {
    if ( !is_single() ){
        return;
    }
    global $post;
    if ( 'publish' !== $post->post_status
		&& 'private' !== $post->post_status) {
        return;
    }
    $args = array(
        'post_type' => 'post',
        'post_status' => array('publish', 'private'),
        'post_per_page' => -1,
        'fields' => 'ids',
        'date_query' => array(
            'before' => $post->post_date,
        ),
    );
    $the_query = new WP_Query($args);
    return $the_query->post_count;
}

简单解释一下:
因为要用到post的ID、post_status和post_date,所以直接用了loop循环中存在的全局变量$post。不用这个全局变量,改用get系列的函数也是一样的。
检索的post类型,我用的是publish和private。这个参是个数组,可以根据需要自行增减。
fields设成ids,意思是返回值接受id。这么写是因为有人说这样可以加快执行速度,并没有实际证据。

date_query是重头戏。
before可以接受的是date string。而无论你的时间格式设成什么样,$post->post_date都刚好是个标准的时间字符串,而且还精确到秒,所以直接放进去即可。
这里其实省略了一个默认参“column”=“post_date”,也就是给before参赋的值。可以选择的还有“post_date_gmt”,“post_modified”,“post_modified_gmt”。都是字面意思,有需要自己替换就行。
还有就是,before默认生成的运算符是小于等于,也就是取得的数包括了当前贴自身。如果要取得除自己以外的数量,自行减1,或者增加参数post__not_in均可达到目的。

对了还有,get_posts跟WP_Query本质上是一个东西,同样的参数,用get_posts调用,也能起到同样的效果。但是实际执行时,get_posts为了得到返回值,需要多执行一次qurey。而使用WP_Query的时候,直接取成员post_count即可,并不需要把post真的检索出来,相对来说效率更高。

此方案的优点是动态获取,删帖或者转换帖子类型,甚至无耻地修改发帖时间,都不会影响序号的连续性。
缺点就是进行了一次数据库操作,会耽误一丢丢时间。不过据说WP_Query默认操作的是缓存,影响应该没那么大。
以上。


  • (1):地球球花演邦女郎的时候已经是五旬老太了,不在讨论之列
  • (2):本作日版发售后3天,任天堂的下一代掌机NDS在北美上市
  • (3):本作两个流行的汉化版都有大问题。一个D商汉化版不能正常存档,另一个汉化版切换到饺子开始的中间几个人物后会死机。
  • (4):五人分工:辽冀鲁,津京,江浙沪,闽粤桂,深圳+长江(武汉)
  • (5):本来还有个汤球球,但他把机器和卡一起卖给了我。
❌
❌