Python三百行代码实现一简约个人博客网站(全网最小巧)

2024-02-07 19:20

本文主要是介绍Python三百行代码实现一简约个人博客网站(全网最小巧),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是全互联网最小巧的博客,没有比这更小的了。虽然小巧,但功能一点儿也不弱,支持文章的分页展示,文章表格,图片和代码语法高亮。文章无限制分类,访问量统计,按时间和按点击量排序,展示最新文章,最热文章,文章留言评论等功能。

前言

如果你也想拥有一个属于自己的个性博客,这种尝试将大幅降低准入门槛,让你看到实现一个个人博客网站是多么的简单。其它的又是建库建表的,或是需要登录管理后台管理,我还是觉得不够简单好用。

用这种写好的markdown文档的形式,你可以直接把markdown笔记变成动态的博客展示出来。后续可基于微信小程序做个入口,如果想要发布文章,则直接把编写好的markdown文件提交发送过去就可以啦,操作使用上更加简单和快捷。这才应该是现在博客该有的特色和创新,原有的旧的登录网站后台编辑和使用的方式,太落后了。

况且使用这种方式还有个好处,可以方便多人同时使用。比如可以在公司内部搭建一个公共博客平台,做个简单入口界面,让每个人都可以往上面提交文档,这也是个不错的内部方案交流平台和技术分享平台。相比传统word文档的方式优点很多,方便文档的查看、归档和线上展示及分享,连留言评论都有啦。

项目开源地址:

tiny-blog: 极小的个人博客,虽然很小,但是很全。使用python+flask+html实现。

GitHub - yangyongzhen/tiny-blog 

体验地址:

我的个人博客

实现原理

其实就是一个基于markdown的轻量级博客,需要按一定格式编写好markdown文件,提交到后台服务。当用户访问网页时由后台读取文件内容并经由流行的markdown-it组件渲染。

后台使用python的flask框架,整个代码仅三百多行。相当的小巧,很容易根据需要修改源码去增加一些其他的功能。当然一个css或js文件都不可能这么短,这里仅指的是后台代码。网页使用了流行的markdown-it(MarkDown渲染),highlight.js(语法高亮)和mermaid.js(画流程图、时序图等的js库)组件。留言评论功能,使用比较火的Valine博客评论系统。

网站模板我是从素材火网站上找了一个好看的博客网站模板。如果你有中意的其他博客网站模板,也可以很容易的改造过来用。文末介绍和分享几个好看的博客模板。

效果展示:

Flask介绍

Flask是一个轻量级的Python Web框架,用于构建Web应用程序和API。它基于Werkzeug工具箱和Jinja2模板引擎,并且具有灵活性和可扩展性。

Flask提供了一些基本的功能,例如路由、请求和响应处理、会话管理等,同时支持各种扩展,可以轻松添加身份验证、数据库集成、邮件发送等功能。由于其简单的学习曲线和活跃的社区支持,Flask已成为最受欢迎的Python Web框架之一。

源码实现

源码实现很简单,仅有三个文件,总代码量三百多行。为了提高访问速度,设计了一种基于字典map的简单数据结构。只有应用启动时加载一次文件,后续文章访问直接从字典数据中取数据,避免每次访问都读文件,提高访问效率。为了方便的查看数据结构,加载完文件后保存了几个json格式的文件。通过json文件很容易看出来。

发表说说和发表文章只需要进入admin界面,输入授权码,任何人都能发表说说和提交文章。

默认授权码111111,你也可以提交个文章进去看看效果。

main.py

# encoding: utf-8
# author:yangyongzhen
from flask import  Flask,render_template,request,redirect
import articles
import atexit
import json
import sysapp=Flask(__name__,template_folder="templates", static_folder="static", static_url_path="/static")# 首页
@app.route('/')
def index():articles.Stat.totalVisit += 1page = 1page = request.args.get('page',1,int)print(page)nums = len(articles.AllArts)print(nums)allpage = nums / 5if nums %5 != 0:allpage = int(nums/5) + 1print(allpage)curArts = articles.AllArtsif (page * 5) < nums :curArts = articles.AllArts[(page-1)*5 : page*5]else:curArts = articles.AllArts[(page-1)*5 : nums]#分页表tabs = []for i in range(0,allpage):print(i)tabs.append(i)print(tabs)return render_template("index.html",arts=curArts,news=articles.NewArts[:9],hots=articles.HotArts[:9],items=articles.ItemList,curPage=page,tab=tabs)  #加入变量传递@app.route('/about')
def about():msg="my name is caojianhua, China up!"return render_template("about.html",data=msg)  #加入变量传递#分类页
@app.route('/items')
def items():try:id = request.args.get('id')print(id)allArts = []allMaps = articles.ItemMap[id]#遍历 hashfor v in allMaps.values():allArts.append(v) #按日期排序allArts.sort(key=lambda x: x['date'],reverse=True)#print(allArts)page = 1page = request.args.get('page',1,int)print(page)nums = len(allArts)print(nums)allpage = int(nums / 5)if nums %5 != 0:allpage = int(nums/5) + 1print(allpage)curArts = allArtsif (page * 5) < nums :curArts = allArts[(page-1)*5 : page*5]else:curArts = allArts[(page-1)*5 : nums]#分页表tabs = []for i in range(0,allpage):#print(i)tabs.append(i)#print(tabs)return render_template("items.html",arts=curArts,item=id,news=articles.NewArts[:9],hots=articles.HotArts[:9],curPage=page,tab=tabs) except Exception as e:print("Exception occured")print(e)return render_template('404.html')# 文章详情页
@app.route('/article_detail')
def article_detail():art = articles.Article("","","","","","","","",0,0)item_index = 0try:id = request.args.get('id')#print(id)#取出分类item = articles.ArtRouteMap[id]['item']print(item)art = articles.ItemMap[item][id]  #art_index  = NewPosts.index(id)articles.Stat.artStat[id]['visitCnt'] += 1articles.Stat.totalVisit += 1articles.ItemMap[item][id]['visitCnt'] = articles.Stat.artStat[id]['visitCnt']#print(art)#print(item_index)#print(art_index)return render_template("article_detail.html",data=art,news=articles.NewArts[:9],hots=articles.HotArts[:9] ) except Exception as e:print("Exception occured")return render_template('404.html')# 说说页面  
@app.route('/moodList')
def moodList():msg="my name is caojianhua, China up!"return render_template("moodList.html",data=msg) # 留言页面 
@app.route('/comment')
def comment():msg="my name is caojianhua, China up!"return render_template("comment.html",data=msg) @app.route('/404')
def error_404():print("error_404")return render_template("404.html") @app.errorhandler(404)
def page_not_found(e):print("page_not_found")print(e)return render_template('404.html'), 404@app.errorhandler(Exception)
def handle_exception(e):# 捕获其他异常print("handle_exception")print(e)return render_template('404.html'), 500def saveData():#保存访问量数据       with open('statistic.json1', 'w',encoding='utf-8') as f:json.dump(articles.Stat.__dict__, f,ensure_ascii=False)# 监控退出时保存统计信息
@atexit.register
def exit_handler():print("应用程序退出")saveData()if __name__=="__main__":#启动时加载访问量数据articles.getPosts()app.run(port=8000,host="127.0.0.1",debug=False)print("over")

articles.py

# encoding: utf-8
# author:yangyongzhen
import glob
import os
import pprint
import hashlib
import json
import statistic#访问量阅读量统计信息
Stat = statistic.AllStat()# AllArts 总的文章,(按时间排过序的)
AllArts = []
# NewArts 最新文章
NewArts = []
# HotArts 热门文章
HotArts = []
# 文章分类信息
ItemList = []ItemMap = {}
ArtRouteMap = {}#文章信息类定义
class Article(object):def __init__(self, id, item, title, date, summary, body, imgFile, author, cmtCnt, visitCnt):self.id = idself.item = itemself.title = titleself.date = dateself.summary = summaryself.body = bodyself.imgFile = imgFileself.author = authorself.cmtCnt = cmtCntself.visitCnt = visitCntdef mPrint(self):print(self.id)print(self.item)print(self.title)print(self.date)print(self.summary)print(self.body)print(self.imgFile)print(self.author)class ArticlesData():def __init__(self):self.item = ""self.articlesMap = {}# ArticleRoute 文章的分类和路径信息
class ArticleRoute:def __init__(self, item, name):self.item = itemself.name = name#文章分类 是个集合类型,无重复元素
class ItemCfg:def __init__(self):self.items = set()def strTrip(src):str = src.replace(" ", "")str = str.replace("\r", "")str = str.replace("\n", "")return str#从文件中读取信息,并返回itemMap,artRouteMap,items
def getPosts():global ItemMap,ArtRouteMap,ItemList,NewArts# 打开访问量统计JSON文件并读取内容with open('statistic.json1', 'r',encoding='utf-8') as file:json_data = file.read()# 将JSON字符串反序列化为字典对象Stat.__dict__ = json.loads(json_data)print(Stat.totalVisit)# 获取"posts/"目录下的所有文件files = glob.glob("posts/*")# 按修改日期进行排序files = sorted(files, key=lambda x: os.path.getmtime(x))articleMap = {}itemMap = {}artRouteMap = {}#文章分类,是个集合类型,无重复items = set()# 遍历文件列表for i, f in enumerate(files):#print(i)#print(f)file = ffile = os.path.basename(file) # 转换路径分隔符print(file)file = os.path.splitext(file)[0]  # 移除".md"后缀fileread = open(f, 'r',encoding='utf-8').read()lines = fileread.split('\n')#print(lines)title = lines[0].strip()date = strTrip(lines[1].strip())summary = lines[2].strip()imgfile = lines[3].strip()id = hashlib.md5(file.encode(encoding='UTF-8'))id = id.hexdigest()#print(id.hexdigest())item = strTrip(lines[4].strip())author = lines[5].strip()imgfile = strTrip(imgfile)body = '\n'.join(lines[6:])  # 获取第6行及以后的行ar = ArticleRoute(item, title)artRouteMap[id] = ar.__dict__visitCnt = 0if id in Stat.artStat:visitCnt = Stat.artStat[id]['visitCnt']#print(visitCnt)else:Stat.artStat[id] = statistic.ArtStat(title,visitCnt,0).__dict__post = Article(id,item,title, date, summary, body, imgfile, author, 0,visitCnt)articleMap[id] = postitems.add(item)#json_data = json.dumps(posts,ensure_ascii=False)#print(json_data)itemList = []for itm in items:itmMp= {}for v in articleMap.values():if(v.item == itm):itmMp[v.id] = v.__dict__itemMap[itm] = itmMpitemList.append(itm)#保存为json文件with open('Articles.json1', 'w',encoding='utf-8') as f:json.dump(itemMap, f,ensure_ascii=False)with open('artRouteMap.json1', 'w',encoding='utf-8') as f:json.dump(artRouteMap, f,ensure_ascii=False)itemList.sort()#遍历字典for key, val in itemMap.items():for idx,art in val.items():AllArts.append(art)HotArts.append(art)        #按日期排序AllArts.sort(key=lambda x: x['date'],reverse=True)#按访问量排序HotArts.sort(key=lambda x: x['visitCnt'],reverse=True)NewArts = AllArtsItemList = itemList#print((HotArts[0]))ItemMap = itemMapArtRouteMap = artRouteMapreturn itemMap,artRouteMap,itemListif __name__=="__main__":p,p1,items = getPosts()#print(p)print(type(p))print(type(p1))print(p['go学习笔记'])print(p1['3eaf98ad2b949b3f93d16aeaa1f45ab0'])print(items)

statistic.py

# encoding: utf-8
# author:yangyongzhen
# 文章和总阅读量统计#文章访问量统计
#param:名称,访问量,评论量
class ArtStat:def __init__(self, title,visitCnt,cmtCnt):self.title = titleself.visitCnt = visitCntself.commentCnt = cmtCnt#总的统计        
class AllStat:def __init__(self):#总访问量self.totalVisit = 0self.artStat = {}if __name__=="__main__":pass

如何使用

除了flask,无其它依赖。下载源码,pip install flask安装好依赖。然后python main.py即可运行起来。编写新文章,需要按照特定格式写前面几行。因为文章作者,文章分类和日期等信息,都在一个文件里写的。

文章内容格式如下(test.md):

This is a title!
2020-10-22
你好aaaaaaaasssssssssssssssss! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
08.jpg
感悟
yangyongzhenThis is the main post!# Markdown1!
## Markdown2!
### 欢迎使用Markdown编辑器Name    | Age
--------|------
Bob     | 27
Alice   | 23你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。```golang
package mainimport "fmt"func main() {fmt.Println("hello ")
}
```

网页前端小技巧 

导航栏选中高亮

网站头部导航栏根据选择自动高亮显示,代码在silder.js中实现:

var obj=null;
var As=document.querySelector(".w_header_nav").getElementsByTagName('a');
obj = As[0];
for(i=1;i<As.length;i++){if(window.location.href.indexOf(As[i].href)>=0)
obj=As[i];}
console.log(obj)
// 添加class属性
obj.classList.add("active");

返回到顶部

返回到顶部,可复用js代码:

var $backToTopEle=$('<a href="javascript:void(0)" class="Hui-iconfont toTop" title="返回顶部" alt="返回顶部" style="display:none">^^</a>').appendTo($("body")).click(function(){$("html, body").animate({ scrollTop: 0 }, 120);
});
var backToTopFun = function() {var st = $(document).scrollTop(), winh = $(window).height();(st > 0)? $backToTopEle.show(): $backToTopEle.hide();/*IE6下的定位*/if(!window.XMLHttpRequest){$backToTopEle.css("top", st + winh - 166);}
};$(function(){$(window).on("scroll",backToTopFun);backToTopFun();});

分页显示js代码 :

/* 
*page plugin 1.0 
*/
(function ($) {//默认参数var defaults = {totalPages: 9,//总页数liNums: 9,//分页的数字按钮数(建议取奇数)activeClass: 'active' ,//active类firstPage: '首页',//首页按钮名称lastPage: '末页',//末页按钮名称prv: '«',//前一页按钮名称next: '»',//后一页按钮名称hasFirstPage: true,//是否有首页按钮hasLastPage: true,//是否有末页按钮hasPrv: true,//是否有前一页按钮hasNext: true,//是否有后一页按钮callBack : function(page){//回掉,page选中页数}};//插件名称$.fn.Page = function (options) {//覆盖默认参数var opts = $.extend(defaults, options);//主函数return this.each(function () {var obj = $(this);var l = opts.totalPages;var n = opts.liNums;var active = opts.activeClass;var str = '';var str1 = '<li><a href="javascript:" class="'+ active +'">1</a></li>';if (l > 1&&l < n+1) {for (i = 2; i < l + 1; i++) {str += '<li><a href="javascript:">' + i + '</a></li>';}}else if(l > n){for (i = 2; i < n + 1; i++) {str += '<li><a href="javascript:">' + i + '</a></li>';}}var dataHtml = '';if(opts.hasNext){dataHtml += '<div class="next fr">' + opts.next + '</div>';}if(opts.hasLastPage){dataHtml += '<div class="last fr">' + opts.lastPage + '</div>';}dataHtml += '<ul class="pagingUl">' + str1 + str + '</ul>';if(opts.hasFirstPage){dataHtml += '<div class="first fr">' + opts.firstPage + '</div>';}if(opts.hasPrv){dataHtml += '<div class="prv fr">' + opts.prv + '</div>';}obj.html(dataHtml).off("click");//防止插件重复调用时,重复绑定事件obj.on('click', '.next', function () {var pageshow = parseInt($('.' + active).html());var nums,flag;var a = n % 2;if(a == 0){//偶数nums = n;flag = true;}else if(a == 1){//奇数nums = (n+1);flag = false;}if(pageshow >= l) {return;}else if(pageshow > 0&&pageshow <= nums/2){//最前几项$('.' + active).removeClass(active).parent().next().find('a').addClass(active);}else if((pageshow > l-nums/2&&pageshow < l&&flag==false)||(pageshow > l-nums/2-1&&pageshow < l&&flag==true)){//最后几项$('.' + active).removeClass(active).parent().next().find('a').addClass(active);}else{$('.' + active).removeClass(active).parent().next().find('a').addClass(active);fpageShow(pageshow+1);}opts.callBack(pageshow+1);});obj.on('click', '.prv', function () {var pageshow = parseInt($('.' + active).html());var nums = odevity(n);if (pageshow <= 1) {return;}else if((pageshow > 1&&pageshow <= nums/2)||(pageshow > l-nums/2&&pageshow < l+1)){//最前几项或最后几项$('.' + active).removeClass(active).parent().prev().find('a').addClass(active);}else {$('.' + active).removeClass(active).parent().prev().find('a').addClass(active);fpageShow(pageshow-1);}opts.callBack(pageshow-1);});obj.on('click', '.first', function(){var activepage = parseInt($('.' + active).html());if (activepage <= 1){return}//当前第一页opts.callBack(1);fpagePrv(0);});obj.on('click', '.last', function(){var activepage = parseInt($('.' + active).html());if (activepage >= l){return;}//当前最后一页opts.callBack(l);if(l>n){fpageNext(n-1);}else{fpageNext(l-1);}});obj.on('click', 'li', function(){var $this = $(this);var pageshow = parseInt($this.find('a').html());var nums = odevity(n);opts.callBack(pageshow);if(l>n){if(pageshow > l-nums/2&&pageshow < l+1){//最后几项fpageNext((n-1)-(l-pageshow));}else if(pageshow > 0&&pageshow < nums/2){//最前几项fpagePrv(pageshow-1);}else{fpageShow(pageshow);}}else{$('.' + active).removeClass(active);$this.find('a').addClass(active);}});//重新渲染结构/*activePage 当前项*/function fpageShow(activePage){var nums = odevity(n);var pageStart = activePage - (nums/2-1);var str1 = '';for(i=0;i<n;i++){str1 += '<li><a href="javascript:" class="">' + (pageStart+i) + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(nums/2-1).find('a').addClass(active);}/*index 选中项索引*/function fpagePrv(index){var str1 = '';if(l>n-1){for(i=0;i<n;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}}else{for(i=0;i<l;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}/*index 选中项索引*/function fpageNext(index){var str1 = '';if(l>n-1){for(i=l-(n-1);i<l+1;i++){str1 += '<li><a href="javascript:" class="">' + i + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}else{for(i=0;i<l;i++){str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'}obj.find('ul').html(str1);obj.find('ul li').eq(index).find('a').addClass(active);}}//判断liNums的奇偶性function odevity(n){var a = n % 2;if(a == 0){//偶数return n;}else if(a == 1){//奇数return (n+1);}}});}
})(jQuery);

使用方法,在需要分页展示的文章下方添加以下div标签:

<div class="page">
</div>

 在网页头部引入以下js:

<script type="text/javascript" src="plugin/fenye.page.js"></script>
<script type="text/javascript">
$(function(){$("#page").Page({totalPages: 7,//分页总数liNums: 5,//分页的数字按钮数(建议取奇数)activeClass: 'activP', //active 类样式定义callBack : function(page){//console.log(page)}});
})
</script>

markdown文档渲染

<ul class="info>
<div class="md_render">
</div>
</ul>
	<script>var md;var defaults = {html: false, // Enable HTML tags in sourcexhtmlOut: false, // Use '/' to close single tags (<br />)breaks: false, // Convert '\n' in paragraphs into <br>langPrefix: 'language-', // CSS language prefix for fenced blockslinkify: true, // autoconvert URL-like texts to linkstypographer: true, // Enable smartypants and other sweet transforms// options below are for demo only_highlight: true,_strict: false,_view: 'html' // html / src / debug};defaults.highlight = function (str, lang) {var esc = md.utils.escapeHtml;if (lang && hljs.getLanguage(lang)) {try {return '<pre class="hljs"><code>' +hljs.highlight(lang, str, true).value +'</code></pre>';} catch (__) {}}return '<pre class="hljs"><code>' + esc(str) + '</code></pre>';};md = window.markdownit(defaults).use(window.markdownitCheckbox).use(window.markdownitEmoji).use(window.markdownitFootnote);var dat = document.querySelector('#enrolled_id').value;$('.md_render').html(md.render(dat));</script>

 这里有个坑需要注意,jinjia2模版是在后端渲染的,所以在网页的js代码中想使用模版变量不是那么美,不能像网页中{{data}}的方式使用。这里采用了一种取巧的方式,通过一个隐藏标签,先把需要的内容在html网页中渲染出来,再在js中通过操作dom的方式去获取。

<input type="hidden"  id="enrolled_id" value="{{ data.body }}">

其他优秀的个人博客推荐

二猫blog-一个简单的Blog站点

POETIZE

樱花庄的白猫 | ねこ・しろ・ましろ

loading...

 Fomalhaut🥝

Twikoo评论系统配置教程(基于腾讯云开发) | 张洪Heo

LinkinStar's Blog

其他资源

(自适应手机端)响应式个人博客网站模板

我的博客模版

JSON在线 | JSON解析格式化—SO JSON在线工具

风宇个人博客

丰富的计算机技术分享,多样化的互联网资源分享,第1页 - 吱吱工具箱butterPig

POETIZE

loading...

Fomalhaut🥝

这篇关于Python三百行代码实现一简约个人博客网站(全网最小巧)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/688666

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n