对兼容各操作系统的Anki选择题模板的更新——提供更方便的笔记修改功能

2021年当我想做一个兼容各操作系统的Anki选择题模板的时候,到处搜索茧中网,根本找不到相关内容,直到偶然在github上看到Simon Lammer的Anki持久化模块,才算真正实现。现在再在茧中网上搜索兼容各种操作系统的Anki选择题模板,已经有很多结果了——我不免猜想是不是直接或间接从我这里得了点启示?如果真得了启示,也不用声明,不妨留个赞。^_^^_^只想拷贝卡片模版内容的可直接滚动到文末,无需看前面的更新说明。

后来看到一个anki插件Edit Field During Review(安装代码:1020366288),提供了在复习界面修改修改笔记内容的功能,十分方便。我对这个插件做了一点微小的修改,使它在复习界面修改笔记时不但可以修改文本内容,还支持用HTML标签改变文本的显示样式,插入表格和图片等,详见anki插件Edit Field During Review的使用及改造。当时有人说还是不够方便,因为还要靠手工输入HTML代码,如果直接有按钮一点就实现文字样式的修改那就好了。今年刚好又打算考试,于是弄个Anki题库帮助学习,复习的时候修改笔记,很多时候只是想把某些文字加个粗换个颜色突出显示一下,输入HTML代码确实比较麻烦,因此对原来的模板进行了更新,实现了在复习界面按几下按钮就改变被选择的文本的显示样式的功能。演示见下图:

目前,这个选择题模板设置有五个字段:Question——选择题题干;Options——选择题选项,Answer——正确答案;Extra——解析;Section——相关知识点所属教材章节。要让上面的演示图片中做的样式修改永久保存到笔记中,必须安装anki插件Edit Field During Review(安装代码:1020366288),并且必须要按照anki插件Edit Field During Review的使用及改造这篇文章的介绍修改插件的源代码,并且在模版中的字段前增加“edit:”过滤器,否则复习时的修改不能保存到笔记中。当然,如果不需要将复习时的修改保存到笔记中,就无需这个插件了。

除了插件支持外,笔记卡片的样式文件要包含如下内容:

/*说明:以下用u,a,i,b四个标签和4个css类定义相同的样式。
卡片背面模板中创建的临时HTML元素可以是u,a,i,b,也可以是span。
创建span元素时为不同样式指定不同类名,创建u,a,i,b时无需指定类名。
创建u,a,i,b时笔记最终保存的HTML字符串较短。
*/
u, .red{
    color:red;
    font-weight: bold;
    text-decoration:none;
}

.orange, a,a:visited,a:hover,a:link,a:active{
    color:#F90;
    font-weight:bold;
}

.green, i{
    font-weight: bold; 
    font-style:normal;color: #0f0;
}

.blue, b{ 
    font-weight: bold; 
    font-style:normal;color: #3cf;
}

卡片背面内容模版中添加以下HTML代码增加4个按钮:

<div id='styleButtons'> 
	<button id="blue_bold">蓝色加粗</button>
	<button id="red_bold">红色加粗</button>
	<button id="green_bold">绿色加粗</button>
	<button id="orange_bold">橙色加粗</button>
</div>

用于为以上按钮提供样式修改功能的JavaScript代码如下:

/*以下对在复习界面中选择的文本的显示样式进行处理*/
	var styleButtonDiv = document.getElementById('styleButtons');
	var styleButtons = styleButtonDiv.getElementsByTagName('button');
	for(i=0;i<styleButtons.length;i++){
		styleButtons[i].onclick=function(ev){
			var selection = document.getSelection();
      		var selectStr = selection.toString();
      		if (selectStr.trim() != '') {
				var rang = selection.getRangeAt(0);
				//卡片样式如果用u,b,i,a等标签名定义,只需声明tmpEle
				var tmpEle
				//卡片样式如果用.red之类的类名定义,可创建span元素
				//var tmpEle = document.createElement('span');
				var eleId=ev.target.getAttribute('id')//获取触发事件的元素的id				
				if(eleId=='blue_bold'){//如果是蓝色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('b');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'blue';
				}else if(eleId=='red_bold'){//如果是红色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('u');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'red';
				}else if(eleId=='green_bold'){//如果是绿色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('i');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'green';
				}else{//如果是橙色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('a');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'orange';
				}
                //将选中的文本插入临时元素内部
				rang.surroundContents(tmpEle);
				rang.deleteContents(); // 删除选中内容
				rang.insertNode(tmpEle); //插入临时元素替换内容
			} else {
				alert('请先选择文本!');
			}
				
		}
	}	

最后,将整个选择题卡片模板文件提供如下:

正面内容模板:

<script>
// v1.1.8 - https://github.com/SimonLammer/anki-persistence/blob/584396fea9dea0921011671a47a0fdda19265e62/script.js
if(void 0===window.Persistence){var e="github.com/SimonLammer/anki-persistence/",t="_default";if(window.Persistence_sessionStorage=function(){var i=!1;try{"object"==typeof window.sessionStorage&&(i=!0,this.clear=function(){for(var t=0;t<sessionStorage.length;t++){var i=sessionStorage.key(t);0==i.indexOf(e)&&(sessionStorage.removeItem(i),t--)}},this.setItem=function(i,n){void 0==n&&(n=i,i=t),sessionStorage.setItem(e+i,JSON.stringify(n))},this.getItem=function(i){return void 0==i&&(i=t),JSON.parse(sessionStorage.getItem(e+i))},this.removeItem=function(i){void 0==i&&(i=t),sessionStorage.removeItem(e+i)},this.getAllKeys=function(){for(var t=[],i=Object.keys(sessionStorage),n=0;n<i.length;n++){var s=i[n];0==s.indexOf(e)&&t.push(s.substring(e.length,s.length))}return t.sort()})}catch(n){}this.isAvailable=function(){return i}},window.Persistence_windowKey=function(i){var n=window[i],s=!1;"object"==typeof n&&(s=!0,this.clear=function(){n[e]={}},this.setItem=function(i,s){void 0==s&&(s=i,i=t),n[e][i]=s},this.getItem=function(i){return void 0==i&&(i=t),void 0==n[e][i]?null:n[e][i]},this.removeItem=function(i){void 0==i&&(i=t),delete n[e][i]},this.getAllKeys=function(){return Object.keys(n[e])},void 0==n[e]&&this.clear()),this.isAvailable=function(){return s}},window.Persistence=new Persistence_sessionStorage,Persistence.isAvailable()||(window.Persistence=new Persistence_windowKey("py")),!Persistence.isAvailable()){var i=window.location.toString().indexOf("title"),n=window.location.toString().indexOf("main",i);i>0&&n>0&&n-i<10&&(window.Persistence=new Persistence_windowKey("qt"))}}</script>

 
<!--正面模板-->
<div class="text" id="question">{{Question}}<span class='imp'>【所属章节:{{Section}}】<span></div>
<ol class="options" id="optionList"></ol>
<div id="options" style="display:none">{{Options}}</div>
<div id="answer" style="display:none">{{text:Answer}}</div>

 
<script>
    var myinfo;
    //if (Persistence.isAvailable()) {
        myinfo = Persistence.getItem();
        if (myinfo == null) {
            myinfo = {
                single: 0, //本次已做全部练习题中单选题数量
                singleCorrect: 0, //本次已做全部练习题中单选题正确数量
                multi: 0, //本次已做全部练习题中多选题数量
                multiCorrect: 0, //本次已做全部练习题中多选题完全正确数量
                partCorrect: 0, //本次已做全部练习题中多选部分正确数量
                multiScore: 0, //本次已做全部练习题中多选题得分
                score: 0, //当前所作练习题得分
                sum: 0, //本次已做全部练习题累计得分
                total: 0, //本次已做练习总数量
                totalScore: 0, //本次已做练习满分
                newOrderOps: [], //当前所作练习题打乱顺序后的选项
                newOrderAnswer: '', //当前所作练习题打乱选项顺序后新的正确答案编号
                choiced: '', //当前所作练习题选中的选项
                ifright: '' //当前所作练习题选中的选项是否正确
            };
        }
        myinfo.total++;
        myinfo.choiced = '';
        myinfo.newOrderAnswer = '';
        myinfo.newOrderOps = [];
 
        var question = document.getElementById("question");
 
        //读入答案,去掉多余字符和空格
        var correctAnswer = document.getElementById('answer').innerHTML
            .toUpperCase().replace(/[^A-Z]+/, "");
        if (correctAnswer.length > 1) { //正确答案大于一个为多选题
            myinfo.totalScore += 2;
            myinfo.multi++;
            question.innerHTML = "<span class='imp'>【多选题】</span>" + question.innerHTML;
        } else { //单选题  
            myinfo.totalScore++;
            myinfo.single++;
            question.innerHTML = "<span class='imp'>【单选题】</span>" + question.innerHTML;
        }
 
        var options = document.getElementById("options"),
            optionList = document.getElementById("optionList");
 
        var s = 0;
        var indexs = [];
        //处理原始顺序的选项,将div标签和br标签以及多余的换行替换掉
        var options = options.innerHTML;
        options = options.replace(/<\/?div>/g, "\n");
        options = options.replace(/\n+/g, "\n");
        options = options.replace(/<br.*?>/g, "\n");
        options = options.replace(/^\n/, "");
        options = options.replace(/\n$/, "");
        //以换行符分隔选项为数组
        options = options.split("\n");
 
        //随机组合选项
        for (var op in options) {
            //随机产生一个索引,如果产生的索引已处理过,继续产生下一个索引,没处理过就中断循环开始处理
            do {
                s = Math.random() * (options.length);
                s = Math.floor(s);
                if (indexs.join().indexOf(s.toString()) == -1) {
                    indexs.push(s);
                    myinfo.newOrderOps.push(options[s]);
                    break;
                }
            } while (true);
            //将随机产生的选项组合成li包着的input和label
            list = document.createElement("li");
            label = document.createElement("label");
            label.innerHTML = options[s];
            var input = document.createElement("input");
				//根据答案字符长短判定应该用多选框还是单选框
            input.type = correctAnswer.length > 1?"checkbox":"radio";
            input.value = s;
			   input.name = "opts";//将选项成组,以防单选题可选择多个选项
				input.id = "opts_" + s;
				label.for = "opts_" + s;
            list.addEventListener("click", clickOption);
            list.appendChild(input);
            list.appendChild(label);
            optionList.appendChild(list);
 
        }
 
        for (i = 0; i < options.length; i++) {
            //将正确答案的字母序号转换成打乱顺序后的字母编号,并记录到myinfo.newOrderAnswer中
            if (correctAnswer.indexOf(String.fromCharCode(65 + indexs[i])) >= 0) {
                myinfo.newOrderAnswer += String.fromCharCode(65 + i);
            }
        }
Persistence.setItem(myinfo);
        //在选项li标签所在区域点击时,实际触发事件的可能是li、label或者input组件,无论是那个组件,都定位到checkbox
        function clickOption(ev) {
            var checkbox = ev.target;
				
            var tagName = checkbox.tagName;
            if (tagName == 'LI') {
                checkbox = checkbox.children[0];
            } else if (tagName == 'LABEL') {
                checkbox = checkbox.parentNode.children[0];
            }
            checkbox.checked = 'checked';
				
            var s = checkbox.value;
            //在打乱顺序后的索引数组中找到选项的新数字序号,再转换成对应的字母编号
            var ch = String.fromCharCode(65 + indexs.join('').indexOf(s.toString()));
            if (myinfo.choiced.indexOf(ch) == -1) {
                if(correctAnswer.length > 1){//多选题,在已选择项上加上一个新选项
						myinfo.choiced += ch;
					}else{//单选题,将已选择项变更为刚选的选项
						myinfo.choiced = ch;						
					}
            } else { //点击已选中的选项则取消该选项的选中状态
                myinfo.choiced = myinfo.choiced.replace(ch, '');
                checkbox.checked = null;
            }
            //if (Persistence.isAvailable()) {
                Persistence.setItem(myinfo);
            /*} else {
                window.myinfo = myinfo;
            }*/
			//根据选项是否被选择赋予不同的显示样式
            for (var j=0;j<optionList.children.length;j++) {
					var ch = String.fromCharCode(65 + j)
					if (myinfo.choiced.indexOf(ch) == -1) {
						optionList.children[j].className = "unchoiced";
					} else {
						optionList.children[j].className = "choiced";
					}
				}
        }
 
    /*} else {//无法持久化js对象,只能针对单面单题练习
    }*/
</script>

背面内容模版:

<!--背面模板-->
<script>
// v1.1.8 - https://github.com/SimonLammer/anki-persistence/blob/584396fea9dea0921011671a47a0fdda19265e62/script.js
if(void 0===window.Persistence){var e="github.com/SimonLammer/anki-persistence/",t="_default";if(window.Persistence_sessionStorage=function(){var i=!1;try{"object"==typeof window.sessionStorage&&(i=!0,this.clear=function(){for(var t=0;t<sessionStorage.length;t++){var i=sessionStorage.key(t);0==i.indexOf(e)&&(sessionStorage.removeItem(i),t--)}},this.setItem=function(i,n){void 0==n&&(n=i,i=t),sessionStorage.setItem(e+i,JSON.stringify(n))},this.getItem=function(i){return void 0==i&&(i=t),JSON.parse(sessionStorage.getItem(e+i))},this.removeItem=function(i){void 0==i&&(i=t),sessionStorage.removeItem(e+i)},this.getAllKeys=function(){for(var t=[],i=Object.keys(sessionStorage),n=0;n<i.length;n++){var s=i[n];0==s.indexOf(e)&&t.push(s.substring(e.length,s.length))}return t.sort()})}catch(n){}this.isAvailable=function(){return i}},window.Persistence_windowKey=function(i){var n=window[i],s=!1;"object"==typeof n&&(s=!0,this.clear=function(){n[e]={}},this.setItem=function(i,s){void 0==s&&(s=i,i=t),n[e][i]=s},this.getItem=function(i){return void 0==i&&(i=t),void 0==n[e][i]?null:n[e][i]},this.removeItem=function(i){void 0==i&&(i=t),delete n[e][i]},this.getAllKeys=function(){return Object.keys(n[e])},void 0==n[e]&&this.clear()),this.isAvailable=function(){return s}},window.Persistence=new Persistence_sessionStorage,Persistence.isAvailable()||(window.Persistence=new Persistence_windowKey("py")),!Persistence.isAvailable()){var i=window.location.toString().indexOf("title"),n=window.location.toString().indexOf("main",i);i>0&&n>0&&n-i<10&&(window.Persistence=new Persistence_windowKey("qt"))}}</script>


 
<div id="performance">正确率:100%</div>
<hr />
<div class="text">{{edit:Question}}</div>
<ol class="options" id="optionList"></ol>
<hr />
<div id="key" class="text"><span class="small_text">上面的选项以<span class="green">此种形式</span>显示的为被你选中的正确选项,以<span class="blue">此种形式</span>显示的为未被你选中的正确选项,以<span class="wrong">此种形式</span>显示的不是正确选项却被你选中了。本题结果如下:</sapn><br/></div>
<hr>
<div class="extra">
    <sapn class="imp">【解析】</sapn><br>{{edit:Extra}}</div>
<div id='styleButtons'> 
	<button id="blue_bold">蓝色加粗</button>
	<button id="red_bold">红色加粗</button>
	<button id="green_bold">绿色加粗</button>
	<button id="orange_bold">橙色加粗</button>
</div>

<script>
	/*以下对在复习界面中选择的文本的显示样式进行处理*/
	var styleButtonDiv = document.getElementById('styleButtons');
	var styleButtons = styleButtonDiv.getElementsByTagName('button');
	for(i=0;i<styleButtons.length;i++){
		styleButtons[i].onclick=function(ev){
			var selection = document.getSelection();
      		var selectStr = selection.toString();
      		if (selectStr.trim() != '') {
				var rang = selection.getRangeAt(0);
				//卡片样式如果用u,b,i,a等标签名定义,只需声明tmpEle
				var tmpEle
				//卡片样式如果用.red之类的类名定义,可创建span元素
				//var tmpEle = document.createElement('span');
				var eleId=ev.target.getAttribute('id')//获取触发事件的元素的id				
				if(eleId=='blue_bold'){//如果是蓝色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('b');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'blue';
				}else if(eleId=='red_bold'){//如果是红色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('u');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'red';
				}else if(eleId=='green_bold'){//如果是绿色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('i');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'green';
				}else{//如果是橙色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('a');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'orange';
				}
                //将选中的文本插入临时元素内部
				rang.surroundContents(tmpEle);
				rang.deleteContents(); // 删除选中内容
				rang.insertNode(tmpEle); //插入临时元素替换内容
			} else {
				alert('请先选择文本!');
			}
				
		}
	}	
	
	/*以下处理对做题结果的判断和输出*/
   var myinfo;
   myinfo = Persistence.getItem();
 
   //计算成绩的函数
   function calcScore() {
            if (myinfo.choiced.length == 0) {
                myinfo.ifright = "为什么一个都不选?"
                myinfo.score = 0;
            } else {
                myinfo.score = 1;
                for (var i = 0; i < myinfo.choiced.length; i++) {
                    if (myinfo.newOrderAnswer.indexOf(myinfo.choiced.charAt(i)) == -1) {
                        myinfo.score = 0;
                        myinfo.ifright = "错误";
                        break;
                    }
                }
                if (myinfo.score != 0) {
                    if (myinfo.newOrderAnswer.length == 1) {
                        myinfo.singleCorrect++;
                        myinfo.score = 1;
                        myinfo.ifright = "完全正确";
                    } else {
                        if (myinfo.choiced.length == myinfo.newOrderAnswer.length) {
                            myinfo.multiCorrect++;
                            myinfo.multiScore += 2;
                            myinfo.score = 2;
                            myinfo.choiced = myinfo.newOrderAnswer;
                            myinfo.ifright = "完全正确";
                        } else {
                            myinfo.partCorrect++;
                            myinfo.score = myinfo.choiced.length * 0.5;
                            myinfo.multiScore += myinfo.score;
                            myinfo.ifright = "不完全正确";
                        }
                    }
                }
            }
            myinfo.sum += myinfo.score;
            Persistence.setItem(myinfo);
        }
        //显示选项
        var optionOl = document.getElementById("optionList");
        ops = myinfo.newOrderOps;
        for (var i = 0; i < ops.length; i++) {
            var ch = String.fromCharCode(65 + i);
            list = document.createElement("li");
            label = document.createElement("label");
            label.innerHTML = ops[i];
            var input = document.createElement("input");
            //根据选择的答案是否有多个字符判断应选用多选框还是单选框
            input.type = myinfo.choiced.length > 1?"checkbox":"radio";
            list.appendChild(input);
            list.appendChild(label);
            optionOl.appendChild(list);
            if (myinfo.newOrderAnswer.indexOf(ch) >= 0) {
                if (myinfo.choiced.indexOf(ch) >= 0) {
                    list.className = 'green';
                    input.checked = 'checked';
                } else {
                    list.className = 'blue';
                }
            } else {
                if (myinfo.choiced.indexOf(ch) >= 0) {
                    list.className = 'wrong';
                    input.checked = 'checked';
                } else {
                    list.className = 'unchoiced'
                }
            }
        }
 
        //显示成绩
        calcScore();
        var performance = document.getElementById("performance");
        var key = document.getElementById("key");
        var total = myinfo.single + myinfo.multi;
        if (typeof(myinfo) != "undefined") {
            var singlePer = myinfo.single == 0 ? "100.00" :
                ((myinfo.singleCorrect / myinfo.single) * 100).toFixed(2);
            var multiErr = myinfo.multi - myinfo.multiCorrect - myinfo.partCorrect
            var multiPer = myinfo.multi == 0 ? "100.00" :
                ((myinfo.multiScore / (myinfo.multi * 2)) * 100).toFixed(2);
            var scorePer = ((myinfo.sum / myinfo.totalScore) * 100).toFixed(2)
            performance.innerHTML = "本次练习<span class='imp'>" + total +
                "</span>题---单选题<span class='imp'>" + myinfo.single +
                "</span>题---多选题<span class='imp'>" + myinfo.multi +
                "</span>题;<br>单选正确<span class='imp'>" + myinfo.singleCorrect +
                "</span>题---单选正确率<span class='imp'>" + singlePer +
                "%</span>;<br>多选正确<span class='imp'>" + myinfo.multiCorrect +
                "</span>题---多选部分正确<span class='imp'>" + myinfo.partCorrect +
                "</span>题---多选错误<span class='imp'>" + multiErr +
                "</span>题---多选得分<span class='imp'>" + myinfo.multiScore +
                "</span>分---多选得分率<span class='imp'>" + multiPer +
                "%</span>;<br>累计得分:<span class='imp'>" + myinfo.sum +
                "</span>分---已做题目满分<span class='imp'>" + myinfo.totalScore +
                "</span>分---得分率<span class='imp'>" + scorePer + "%</span>";
            key.innerHTML += "<div>正确答案:<span class='imp'>" + myinfo.newOrderAnswer +
                ";</span>你的答案:<span class='imp'>" + myinfo.choiced +
                ";</span>结果判定:<span class='imp'>" +
                myinfo.ifright + "</span>;本题得分:<span class='imp'>" +
                myinfo.score + "</span>。</div>";
        }
    //} else {}
</script>

样式:

.card { font-family: Cambria-modify,Aa虎头虎脑,哈天随性体,干就完事了简,微软雅黑; font-size:1.3em; text-align:left; 
			color: white; background-color:#000000;}
	table{border-collapse:collapse; }
	td{padding:5px;text-align:center;border:2px solid green;vertical-align: middle;}
	td.left{text-align:left;}
	td.red{
		border-right: solid thick red;
	}
	span {display:inline-block;}
	hr{border: none;
		height: 5px;
		background-color:yellow;}
	p{text-indent:2em;}
	div{margin:5px auto }
	.text{color:#ff0;font-weight:bold;font-size:1.2em;}
	.orange, .imp,a, a:visited,a:hover,a:link,a:active{color:#F90;font-weight:bold;}
	u, .red{color:red;font-weight: bold;text-decoration:none;}
	.unchoiced{ color: white;}
	.choiced{font-weight: bold; color: #f00;background-color:green;}
	.extra{ margin-top:15px; font-size:1.2em; color: #eeeebb; text-align:left;line-height:1.5em;}
	.green,i{  font-weight: bold; font-style:normal;color: #0f0;}
	.blue,b{ font-weight: bold; font-style:normal;color: #3cf;}
	.wrong{  font-weight: bold;  color: red;text-decoration:line-through;}
	.options{ list-style:upper-latin;font-size:1.2em;}
	.options *{ cursor:pointer;}
	.options *:hover[class="options"]{ font-weight:bold;color: #f90;}
	.options li{ margin-top:0.8em;}
	/*下面两行样式定义决定是否显示选项前面的圆形或方形框,注释掉就会显示*/
	.options input[type="radio"]{display:none;}
	.options input[type="checkbox"]{display:none;}
	#performance{ text-align:left; font-size:16px;}0

最后说明:由于本文的功能用到了Anki插件,因此不支持插件的安卓和iOS版的Anki不能应用本文的功能。本文在windows11及Anki2.1.54上完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/734456.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【百问大模型01】GPT4o最新特性介绍

1、GPT4o 最大的特性是对话响应速度很快 端到端能力300ms&#xff1b;之前是语音转成文字&#xff0c;再来理解分析&#xff1b;现在是直接端到端。 1&#xff09;丰富的语音风格 2&#xff09;理解语音内外的内容 3&#xff09;发出非语音的声音 4&#xff09;自然而及时…

苹果mac电脑救星CleanMyMac让我的电脑重获新生!

&#x1f389; 发现电脑的救星&#xff01;CleanMyMac让我的电脑重获新生&#xff01; CleanMyMac绿色免费版下载如下&#xff1a;记得保存哈&#xff0c;以防失效&#xff1a; https://pan.quark.cn/s/9b08114cf404 CleanMyMac X2024全新版下载如下: https://wm.makeding.…

6/22 第四周 python操作word

学习到了word有四个段落&#xff0c;都可以通过python来操作。 并且课程的体系&#xff0c;只是一个启蒙&#xff0c;需要在公司的项目中熟悉&#xff0c;从而具备专项测试的能力。 后续每天的学习笔记也需要侧重于理解的部分。

阿里云发送验证码流程

目录 1. 阿里云短信服务简介 2. 阿里云验证码发送流程 2.1 申请阿里云短信服务 2.2 短信模板及阿里云秘钥 1.开发者可以在自己的应用程序中集成短信发送功能。绑定发起测试的手机号&#xff0c;需要绑定的手机号才能成功发送验证码&#xff0c;其他的用户手机号发送的验…

2.APP测试-安卓adb抓取日志

1.打开手机的开发者模式&#xff0c;打开USB调试 &#xff08;1&#xff09;小米手机打开开发者模式&#xff1a; 【设置】-【我的设备】-【全部参数信息】-快速多次点击【OS版本】-进入开发者模式 &#xff08;2&#xff09;连接手机和电脑&#xff0c;手机打开USB调试 【设置…

智能虚拟集群系统在酒店楼宇中的应用

随着城市化建设的不断发展&#xff0c;酒店楼宇等建筑规模不断扩大、地面/地下楼层不断增加。面对日益复杂的通信环境&#xff0c;酒店服务和管理人员对无线通信系统的稳定性、覆盖范围、话音清晰度、应急响应能力等方面均提出了更高的需求。 需求痛点 面对繁忙的工作&#x…

Adobe Illustrator 矢量绘图软件下载,Ai 2024最新版获取!

Adobe Illustrator&#xff0c;无论是艺术品、图标还是海报等设计作品&#xff0c;Adobe Illustrator都能以超凡的表现力展现出设计师们的创意与才华。 近年来&#xff0c;随着人工智能技术的迅猛发展&#xff0c;各行各业都纷纷将这一技术引入自身领域&#xff0c;以提升工作效…

【洛谷P3366】【模板】最小生成树 解题报告

洛谷P3366 -【模板】最小生成树 题目描述 如题&#xff0c;给出一个无向图&#xff0c;求出最小生成树&#xff0c;如果该图不连通&#xff0c;则输出 orz。 输入格式 第一行包含两个整数 N , M N,M N,M&#xff0c;表示该图共有 N N N 个结点和 M M M 条无向边。 接下…

晶谷高温烧结导电浆料用低熔点玻璃粉 晶谷耐高温导电漆导电油墨高温玻璃粉

晶谷浆料玻璃粉是一种用于电子浆料的材料&#xff0c;它在电子浆料中起到粘结和降低烧结温度的作用&#xff0c;能够提高浆料与基材之间的结合力。 浆料玻璃粉的性能特点包括&#xff1a; - 软化点&#xff1a;软化点在350至650度之间。 - 热膨胀系数&#xff1a;热膨胀系数…

实现文件分片合并功能并使用Github Actions自动编译Release

一、编译IOS镜像 1.1 编译 起因是公司电脑使用的Win11 23H2的预览版&#xff0c;这个预览版系统的生命周期只到2024-09-18&#xff0c;到期后就会强制每两小时重启。这是Windows强制升级系统的一种手段。 虽然公司里的台式电脑目前用不到&#xff0c;但是里面还保留许多旧项…

上交商汤联合提出一种虚拟试穿的创新方法,利用自监督视觉变换器 (ViT) 和扩散模型

上交&商汤联合提出一种虚拟试穿的创新方法&#xff0c;利用自监督视觉变换器 (ViT) 和扩散模型&#xff0c;强调细节增强&#xff0c;通过将 ViT 生成的局部服装图像嵌入与其全局对应物进行对比。虚拟试穿体验中细节的真实感和精确度有了显着提高&#xff0c;大大超越了现有…

教大家封装一个基础el-table 行内气泡编辑框,你一定用的到

今天的任务就是封装这个用element ui 组件来封装&#xff0c;如果让你封装你会怎么封装呢&#xff1f; 不说废话了&#xff0c;直接上代码 新建一个EditablePopoverColumn.vue组件文件 <template><el-table-column :prop"prop" :label"label"&…

探索ChatTTS项目:高效的文字转语音解决方案

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f4d2; ChatTTS &#x1f4d2;&#x1f4dd; 项目介绍&#x1f4dd; 项目亮点&#x1f4dd; UI &#x1f388; 项目地址 &#x1f388; &#x1f4d6; 介绍 &#x1f4d6; 在AI技术迅速发展的今天&#xff0c;文本到语音&…

Mac OS 如何在命令行下启动Docker

现象 当用 Mac air作为服务器时&#xff0c;远程登录上去后想使用 docker&#xff0c;却报如下错&#xff1a; Cannot connect to the Docker daemon at unix:///Users/aborn/.docker/run/docker.sock. Is the docker daemon running? 原因分析 因为 docker 有一个守护进程…

array_key_exists() expects parameter 2 to be array, null given

公众号获取微信服务器IP地址 错误代码如下 public function getwxIP(){//获取微信服务器IP地址$accessToken $this->getwxoaiAccessToken();$userToken new UserToken();$result $userToken->curl_get("https: //api.weixin.qq.com/cgi-bin/get_api_domain_ip…

根据状态转移写状态机-二段式

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 描述 题目描述&#xff1a; 如图所示为两种状态机中的一种&#xff0c;请根据状态转移图写出代码&#xff0c;状态转移线上的0/0等表示的意思是过程中data/flag的值。 要求&#xff1a; 1、 必须使用对应类型的状…

C++ 79 之 自己写异常类

#include <iostream> #include <string> using namespace std;class MyOutOfRange : public exception{ // 选中exception右键 转到定义 复制一份 virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW 进行函数重写 public: string m_msg;M…

初学者的TensorFlow 2.0 开发环境安装 -《MCU嵌入式AI开发笔记》(第七集)

MCU嵌入式AI开发笔记 初学者的TensorFlow 2.0 开发环境安装 -《MCU嵌入式AI开发笔记》&#xff08;第七集&#xff09;。抖音、B站、视频号等站点搜索柔贝特三哥&#xff0c;《MCU嵌入式AI开发笔记》视频同步更新&#xff0c;视频详细讲解。 07 初学者的 TensorFlow 2.0 教程 …

openEuler23.09安装Postgresql16.3

openEuler23.09安装Postgresql16.3&#xff0c;基于源代码编译安装PostgreSQL的基本步骤 一、PostgreSQL数据库服务环境搭建 操作系统版本 openEuler-23.09-x86_64-dvd.iso &#xff0c;安装步骤此处省略。。。 最常用且直接的方法来查看openEuler的版本号是查看/etc/os-rel…

“论软件系统建模方法”必过范文,软考高级,系统架构设计师论文

论文真题 软件系统建模(Software System Modeling)是软件开发中的重要环节,通过构建软件系统模型可以帮助系统开发人员理解系统、抽取业务过程和管理系统的复杂性,也可 以方便各类人员之间的交流。软件系统建模是在系统需求分析和系统实现之间架起的一 座桥梁,系统开发人…