记一次Python MRO多继承使用
引言 之前只是看书的时候看过Python多继承的MRO顺序, 从来没在代码里面具体实践过, 今天终于遇到了一次. 在写NWU.ICU的过程中, 有课程评价一项, 建立Model的时候, 为了实现标记删除, 继承了自定义的SoftDeleteModel模型, class Review(SoftDeleteModel): .... pinyin = models.TextField(verbose_name='拼音', blank=True) search_vector = SearchVectorField(null=True) objects = SearchManager() SoftDeleteModel如下 class SoftDeleteManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(is_deleted=False) class SoftDeleteModel(models.Model): is_deleted = models.BooleanField(default=False) deleted_at = models.DateTimeField(null=True, blank=True) objects = SoftDeleteManager() all_objects = models.Manager() def soft_delete(self): self.is_deleted = True self.deleted_at = timezone.now() self.save() soft_delete_signal.send(sender=self.__class__, instance=self) def restore(self): self.is_deleted = False self.deleted_at = None self.save() class Meta: abstract = True 概括就是删除的时候标记is_deleted为true, 并且重写了get_queryset方法, 使得model.objects.get()时, 让已被标记删除的数据不被查询到. 这本来工作好好的, 但为了引入拼音模糊搜索功能, 我在Review模型, 加了几行, 也就是上文里面的 pinyin = models.TextField(verbose_name='拼音', blank=True) search_vector = SearchVectorField(null=True) objects = SearchManager() 使得我的model.objects.get()一直可以获取到已经被标记删除的数据. 解决方案 其中SearchManager如下 class SearchQuerySet(models.QuerySet): def search(self, query, query_table_name): ... class SearchManager(models.Manager): def get_queryset(self): return SearchQuerySet(self.model, using=self._db) def search(self, query, page_size=10, current_page=1): ... search_results = self.get_queryset().search(query, query_table_name) return ... 原因很明显, objects = SearchManager()中get_queryset的覆盖了我在SoftDeleteModel定义的objects的原有方法. ...
数学: ab+1整除a^2+b^2, 证明(a^2+b^2)/(ab+1)是完全平方数
问题 设$a$和$b$为正整数, 且$ab+1$整除$a^2+b^2$. 证明$\frac{a^2+b^2}{ab+1}$是完全平方数. 前置知识 完全平方数 如果$a\in N^*$(正整数), 如果$a^2=b$, 那么我们称$b$为完全平方数. 整除 为了智械危机的快速来临, 在这里讲解一下整除:) 如果$\frac{b}{a}=c$, 且$c\in N^*$, 那么我们称a可以整除b. 解题思路 请先尝试一下自己解题, 五分钟没有思路的情况下, 再接着往下看. 证明思路 相信大家还记得高中数学的"韦达定理"(Vieta’s theorem), 其出自于一个处理数论的证明技巧: 韦达跳跃(Vieta jumping), 除了韦达定理外, 还包括了另一个部分, 无穷递增法(method of infinite descent) 韦达定理描述为: 在二元一次方程中, 两个根的和,积与abc(abc为二元一次方程的项)的关系 假设一元二次方程$ax^2+bx+c=0$有两个实数根, 设其为$x_1,x_2$, 则$x_1+x_2=-\frac{b}{a}$, $x_1*x_2=\frac{c}{a}$ 具体推导过程不表. 无穷递增法是一种反证法, 用自然语言表述为 假设方程有解, 并假设X为最小解, 接着再从X出发, 尝试推导出一个更小的解Y. 若能推导成功, 则与刚才假设的"X为最小解"矛盾, 因此证明此方程无解. 回到最开始的问题中, $ab+1$可以整除$a^2+b^2$, 因此$\frac{a^2+b^2}{ab+1}$是一个正整数, 设其为$k$. 接着我们假设有正整数$a,b$满足$\frac{a^2+b^2}{ab+1}=k$, 而$k$不是完全平方数. 最后, 假设在所有满足条件2的正整数中, 有一组是$a_1,b_1$, 他们拥有最小的和, 其中$a_1>b_1$. 因此, 如果我们能证明, 如果有一组数可以比比$a_1,b_1$还要小, 那么我们条件2的假设:$k$不是完全平方数, 就不成立了, 即证明了$k$是完全平方数. 开始解题 $$ \frac{a_1^2 + b_1^2}{a_1 b_1 + 1} = k \tag{1} $$ ...
根据地平线确定自己所在楼层
这张hackerGame2021的图片让我有的这个想法 确定拍照者所在楼层, , 可以数清楚对面有几层楼, 这里只能假设拍摄者所在的楼和对面楼长得一样. 拍摄者的视线是这样的, 绿色为拍摄者所在楼层, 橙色为对面楼, 红色为视线, 椭圆为地球.因为地面的弧度相对于两个楼之间很小, 所以可以近似看成是一个平面. 得到近似三角形, $$ \frac{x_2-x_1}{x_2}=\frac{y_1}{y_2} $$ 因为x2相对于x1近乎无限大, 所以等式左边等于1, 所以y1=y2, 故我们和海平面视线相交处与对面楼的交点, 就是我们所在的楼层高度. 因此是14楼
宁芝niz 68键位静电容键盘使用体验
引言 在此之前一直使用的是红轴机械键盘和笔记本自带键盘, 早就听闻静电容手感如何如何, 终于在去年买了一把, 35g 68键 侧刻版本. 物理使用体验 手感 手感是十分轻柔, 轻柔的让人感觉只要在上面拂过就可以打出字来, 但过于轻柔会导致手无意识的放在Space, Tab上时, 屏幕上跳出一堆空格或乱窜. 35g的键盘赠送了10g的压力弹簧, 可以根据自己选择安装在不同的键位上, 但部分按键安装会有一点点"弹簧音", 不知是通病还是偶发事件. 35g的触发力度在长时间Coding和打字的情况下是十分舒服的, 但如果用其来打游戏, 就会出现因为上文中提到的“手感异常轻柔”而导致的一系列误触问题, 比如用来打csgo会经常无意识的按到Space导致自己在掩体后面跳起来而被空摘. 综上这键盘在我的几个月使用体验下来, 只适合码字完全不适合打游戏. 声音 声音的话我个人认为是相当舒服的, 轻柔不扰人, 在办公室或者说图书馆使用是完全没问题的, 同时自己听起来很有敲击感, 戴上耳机后又会完全听不见. 续航 续航十分短, 充满电的情况下连续使用10天左右就已经没电了, 需要插电充电. 当然你可以通过c-c的线来把它当作有线键盘使用几个小时, 几个小时足矣充满电了. 同时他的开关不是有一个实体按钮来进行操作, 而是通过tab左边键盘侧边的一个小圆按钮长按来进行开关, 当你几个小时不用导致键盘自动关机的时候(注意是自动关机而不是休眠), 你就需要重新按小圆按钮来进行开机, 体验上不如有实体按钮来操作开关机的其他无线键盘来的爽, 比如mx keys你即使一天没用, 随便按下键盘就可自动开机. 自动关机共有四个挡位, 1,2,3和永久不关机, 在一天使用12h并永不关机的情况下续航大概10天, 相较于一般的无线键盘少很多. 键位体验 从图片中可以看出来, F键全都没了, 需要配合fn键组合按键才能正常使用, 而在日常工作中需要高频使用F5,F9,F12, 十分不爽. 蓝牙可以选择三个设备, 但不能同时连接, 连接一个就会断掉另一个, 在c-c连接设备的时候可以通过组合按键来实现蓝牙连接其他设备. 可以通过fn+command(alt)来切换win/mac键位, 关机保存, 保存在你选择的蓝牙设备中, 比如你1号设备是win, 2号设备是mac, 你将2号设备设为了mac键位, 那么这个设置就会保存在2号键位. 另外在Mac系统下, 切换同个应用的不同窗口需要使用到Ctrl+`组合键, 这个键盘1左边的键位不是`而是Esc, 需要你用一种极其别扭的手势来进行这个操作, 当然这个是68键的问题而不应该是这个键盘的问题. ...
Hello Hugo
Hello World! Migrate blog to Hugo today!
密码学RSA非对称算法原理
首先我们看一个非对称加密在现实中的具体应用(笑 有学生没带作业, 老师需要在群里提醒家长, 但直接发学生的照片就会被所有家长知道没带作业的学生是谁, 这样会导致学生和家长都很没面子. 所以老师使用了公钥(大家都能看到的): 学生的鞋子. 大家看到的只是三个学生的鞋子, 并不知道学生具体是谁, 即看到的是密文. 家长看到了鞋子, 因为拥有私钥(即只有家长自己知道自己家孩子穿的什么样的鞋), 所以可以知道老师发的照片中学生是谁, 破解了密文, 这就完成了一次非对称性的加密和解密. 换成严谨一点的语言描述, 如下: A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥。 A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。 A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。 A将这个消息发给B(已经用B的公钥加密消息)。 B收到这个消息后,B用自己的私钥解密A的消息。其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。 从上文可以看出, 非对称加密体系不要求通信双方事先传递密钥或有任何约定就能完成保密通信,并且密钥管理方便,可实现防止假冒和抵赖,因此,更适合网络通信中的保密通信要求. 原理 根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥. 获取公钥私钥过程 选择两个很大的素数p和q 这里取$p=67,q=71$ 计算$n=p⋅q, n$公开, 即为公钥的一部分. (如果$n=p⋅q=4757_{(10)}=1001010010101_{(2)}$, 二进制的n为13位, 则称该加密为13位加密, 实际应用中一般才用1024位或2048位的加密来保证安全). 计算 n 的欧拉函数 $φ(n)$ 设$m=φ(n)=φ(q)⋅φ(q)=(q−1)(p−1)=66×70=4620.$ 在数论,对正整数n,欧拉函数φ(n)是小于或等于n的正整数中与n互质的数的数目(因此φ(1)=1(1), φ(8)=4(1,3,5,7), 这里的p,q都是质数, 所以从1到(n-1)都与其互质, φ(n)=n−1 再选一个数字e, e与m互质, 且1<e<m, e也是公开的, 即公钥的另一部分. 这里取e=101, 这里e的选择有一个小坑, 我们一会再说 找到一个整数 d,可以使得 e∗d 等价于$e*d−1=y∗m, y∈N+$, 将数字带入$101×d−1=y×4757$, 这里可用扩展欧几里得算法解, 下文给出过程, 这里省略. 给出结果$(d,y)=(1601,35)$, 即$d=1601$, 从这里可以看出, d是由我们上面第4步任意取的e决定的, 所以我们只要选取不同的e, 就可以得到不同的d, 就是不同的密钥对. ...