diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index 60d63a1bd..0b764202f 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -462,7 +462,7 @@ pop_box_new(htmlvalue, 480, 182); // myshixun_manager power is_teacher resData.power = 0 resData.myshixun_manager = false - resData.is_teacher = false + // resData.is_teacher = false if (resData.user.identity === EDU_ADMIN) { resData.power = 1 @@ -513,6 +513,14 @@ pop_box_new(htmlvalue, 480, 182); loading: true, currentGamePassed: false, // 切换game时重置passed字段 }) + + // test + // var data = {"st":0,"discusses_count":12,"game_count":6,"record_onsume_time":5.303,"prev_game":"q67plhfjaogy","next_game":"lfrwm2ohiate","praise_count":0,"user_praise":false,"time_limit":180,"tomcat_url":"http://47.98.226.234","is_teacher":true,"myshixun_manager":false,"game":{"id":1964918,"myshixun_id":510423,"user_id":73892,"created_at":"2019-06-24T11:22:58.000+08:00","updated_at":"2019-06-25T11:15:48.000+08:00","status":0,"final_score":0,"challenge_id":573,"open_time":"2019-06-24T11:22:58.000+08:00","identifier":"yrsxolqk6zcp","answer_open":0,"end_time":null,"retry_status":0,"resubmit_identifier":null,"test_sets_view":false,"picture_path":null,"accuracy":null,"modify_time":null,"star":0,"cost_time":3966,"evaluate_count":1,"answer_deduction":0},"challenge":{"id":573,"shixun_id":186,"subject":"应用模型做预测","position":4,"task_pass":"####本关任务\r\n本关卡学习如何应用机器学习模型来做预测。\r\n\r\n####相关知识\r\n在前一关卡中,我们一起探讨了机器学习的一般原理,并建立了一个非常简单的电影评分模型Model 0:\r\n\r\n评分 = **大众对电影的平均评分** + **用户个人的给分偏好** + **电影的评分偏好**\r\n\r\n针对这个模型,我们设计了一个非常朴素的预测模型Baseline,直接从数据集中统计得到上述三个参数的值。\r\n\r\n在本关卡中,我们将应用这个模型对用户和电影的评分做出预测。\r\n\r\n####编程要求\r\n回顾Model 0的预测评分公式:\r\n```latex\r\nf(u,m)=g+\\alpha(u)+\\beta(m)\r\n```\r\n\r\n我们的Baseline模型得到了$$g$$、$$\\alpha$$和$$\\beta$$三种参数,下面我们实现predict函数,来对测试数据集中未知的用户电影评分进行预测,需要填充的代码块如下:\r\n```python\r\n# -*- coding:utf-8 -*-\r\n\r\ndef predict(g, alpha, beta, test_data):\r\n\t\"\"\"预测用户对电影的评分\r\n\t参数:\r\n\t\tg - 浮点数,模型参数平均电影评分\r\n\t\talpha - 浮点数组,用户评分偏差参数数组\r\n\t\tbeta - 浮点数组,电影评分偏差参数数组\r\n\t\ttest_data - Pandas的DataFrame对象,有两列'user','movie',是测试数据集\r\n\t返回值:\r\n\t\tret - 浮点数数组,预测的评分数组,举例ret[10],表示第10组用户和电影对的评分值\r\n\t\"\"\"\t\r\n\tret = []\r\n\tN = len(alpha)\r\n\tM = len(beta)\r\n\t\r\n\t# 请在此添加实现代码\r\n\t#********** Begin *********#\r\n\t\r\n\t#********** End *********#\r\n\t\r\n\treturn ret\r\n```\r\n\r\n####本关任务\r\n本关卡的测试数据来自内置测试文件,平台将比对您所编写函数的预测评分与正确评分,只有所有数据全部计算正确才能进入下一关。","score":500,"path":"src/step4/doprediction.py","st":0,"web_route":null,"modify_time":null},"shixun":{"id":186,"name":"理解机器学习基本概念:从电影评分预测讲起","user_id":24758,"gpid":3676,"visits":622,"created_at":"2017-08-25T18:07:41.000+08:00","updated_at":"2019-06-02T11:05:20.000+08:00","status":2,"language":"MachineLearning","authentication":false,"identifier":"58DRWG63","trainee":3,"major_id":635,"webssh":0,"homepage_show":false,"hidden":false,"fork_from":null,"can_copy":true,"modify_time":"2017-09-29T21:42:16.000+08:00","reset_time":"2017-09-29T21:42:16.000+08:00","publish_time":"2017-09-29T10:58:13.000+08:00","closer_id":null,"end_time":null,"git_url":"educoder/58drwg63","vnc":false,"myshixuns_count":318,"challenges_count":6,"use_scope":0,"mirror_script_id":0,"image_text":null,"code_hidden":false,"task_pass":false,"exec_time":180,"test_set_permission":true,"sigle_training":false,"hide_code":false,"multi_webssh":false,"excute_time":null,"repo_name":"educoder/58drwg63","averge_star":4.9,"opening_time":null,"users_count":10,"forbid_copy":false,"pod_life":0},"myshixun":{"id":510423,"shixun_id":186,"is_public":true,"user_id":73892,"gpid":null,"created_at":"2019-06-24T11:22:55.000+08:00","updated_at":"2019-06-24T13:56:40.000+08:00","status":0,"identifier":"7pkwxim9eh","commit_id":"ff7c6652fdfdf62eaa1316d39400ebdbd6cb81fb","modify_time":"2017-09-29T21:42:16.000+08:00","reset_time":"2017-09-29T21:42:16.000+08:00","system_tip":false,"git_url":null,"onclick_time":"2019-06-24T11:22:55.000+08:00","repo_name":"p35840769/7pkwxim9eh20190624112255"},"user":{"user_id":73892,"login":"p35840769","name":"韩半安","grade":6895,"image_url":"avatars/User/b","school":"国防科技大学","identity":6},"tpm_modified":false,"tpm_cases_modified":false,"mirror_name":["MachineLearning"],"has_answer":true,"test_sets":[{"is_public":true,"result":false,"input":"771 253 360 99 8 759 976 387 873 829 437 53 854 148 447 179 246 810 158 653 583 929 691 892 263 230 637 221 7 652 127 965 767","output":"3.577 -0.329 2.648 4.727 4.351 2.616 3.496 3.059 3.470 3.166 3.064 2.716 3.712 4.003 3.064 3.462 4.004 2.067 3.860 0.121 3.807 3.735 4.230 3.137 4.431 2.468 4.018 5.218 4.351 4.121 4.050 4.587 3.777","actual_output":"Traceback (most recent call last):\r\n File \"src/step4/main.py\", line 3, in \u003cmodule\u003e\r\n from doprediction import predict\r\nImportError: cannot import name 'predict'\r\n","compile_success":1},{"is_public":false,"result":false,"compile_success":1}],"allowed_unlock":true,"last_compile_output":"共有2组测试集,其中有2组测试结果不匹配。详情如下:","test_sets_count":2,"sets_error_count":2} + // data.shixun.vnc = true + // data.vnc_url= "http://47.96.157.89:54144/vnc_lite.html?password=headless" + + // this._handleResponseData(data) + // return axios.get(url, { // https://stackoverflow.com/questions/48861290/the-value-of-the-access-control-allow-origin-header-in-the-response-must-not-b @@ -835,7 +843,8 @@ pop_box_new(htmlvalue, 480, 182); {this.state.gDialogContentText} - + {/* mb20 加了有样式问题 */} + { this.isSingleButton ?
*/} - {/* { showIframeContent && vnc_url ? */} + > + : +
@@ -143,6 +145,9 @@ class MainContent extends Component {
+ + + }
diff --git a/public/react/src/modules/page/VNCDisplay.js b/public/react/src/modules/page/VNCDisplay.js index b8840fe02..1e443ed1d 100644 --- a/public/react/src/modules/page/VNCDisplay.js +++ b/public/react/src/modules/page/VNCDisplay.js @@ -1,154 +1,154 @@ -// import React, { Component } from 'react'; +import React, { Component } from 'react'; -// import RFB from '@novnc/novnc/lib/rfb.js'; +import RFB from '@novnc/novnc/lib/rfb.js'; -// const $ = window.$; -// // const showIframeContent = window.location.search.indexOf('vnc=1') != -1; -// class VNCDisplay extends Component { -// componentDidMount() { -// console.log(RFB) +const $ = window.$; +// const showIframeContent = window.location.search.indexOf('vnc=1') != -1; +class VNCDisplay extends Component { + componentDidMount() { + console.log(RFB) -// let rfb; -// let desktopName; -// // When this function is called we have -// // successfully connected to a server -// function connectedToServer(e) { -// status("Connected to " + desktopName); -// } -// // This function is called when we are disconnected -// function disconnectedFromServer(e) { -// if (e.detail.clean) { -// status("Disconnected"); -// } else { -// status("Something went wrong, connection is closed"); -// } -// } -// // When this function is called, the server requires -// // credentials to authenticate -// function credentialsAreRequired(e) { -// const password = prompt("Password Required:"); -// rfb.sendCredentials({ password: password }); -// } -// // When this function is called we have received -// // a desktop name from the server -// function updateDesktopName(e) { -// desktopName = e.detail.name; -// } -// // Since most operating systems will catch Ctrl+Alt+Del -// // before they get a chance to be intercepted by the browser, -// // we provide a way to emulate this key sequence. -// function sendCtrlAltDel() { -// rfb.sendCtrlAltDel(); -// return false; -// } -// // Show a status text in the top bar -// function status(text) { -// document.getElementById('status').textContent = text; -// } -// // This function extracts the value of one variable from the -// // query string. If the variable isn't defined in the URL -// // it returns the default value instead. -// function readQueryVariable(name, defaultValue) { -// // A URL with a query parameter can look like this: -// // https://www.example.com?myqueryparam=myvalue -// // -// // Note that we use location.href instead of location.search -// // because Firefox < 53 has a bug w.r.t location.search -// const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), -// match = document.location.href.match(re); -// if (typeof defaultValue === 'undefined') { defaultValue = null; } -// if (match) { -// // We have to decode the URL since want the cleartext value -// return decodeURIComponent(match[1]); -// } -// return defaultValue; -// } -// document.getElementById('sendCtrlAltDelButton') -// .onclick = sendCtrlAltDel; -// // Read parameters specified in the URL query string -// // By default, use the host and port of server that served this file + let rfb; + let desktopName; + // When this function is called we have + // successfully connected to a server + function connectedToServer(e) { + status("Connected to " + desktopName); + } + // This function is called when we are disconnected + function disconnectedFromServer(e) { + if (e.detail.clean) { + status("Disconnected"); + } else { + status("Something went wrong, connection is closed"); + } + } + // When this function is called, the server requires + // credentials to authenticate + function credentialsAreRequired(e) { + const password = prompt("Password Required:"); + rfb.sendCredentials({ password: password }); + } + // When this function is called we have received + // a desktop name from the server + function updateDesktopName(e) { + desktopName = e.detail.name; + } + // Since most operating systems will catch Ctrl+Alt+Del + // before they get a chance to be intercepted by the browser, + // we provide a way to emulate this key sequence. + function sendCtrlAltDel() { + rfb.sendCtrlAltDel(); + return false; + } + // Show a status text in the top bar + function status(text) { + document.getElementById('status').textContent = text; + } + // This function extracts the value of one variable from the + // query string. If the variable isn't defined in the URL + // it returns the default value instead. + function readQueryVariable(name, defaultValue) { + // A URL with a query parameter can look like this: + // https://www.example.com?myqueryparam=myvalue + // + // Note that we use location.href instead of location.search + // because Firefox < 53 has a bug w.r.t location.search + const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), + match = document.location.href.match(re); + if (typeof defaultValue === 'undefined') { defaultValue = null; } + if (match) { + // We have to decode the URL since want the cleartext value + return decodeURIComponent(match[1]); + } + return defaultValue; + } + document.getElementById('sendCtrlAltDelButton') + .onclick = sendCtrlAltDel; + // Read parameters specified in the URL query string + // By default, use the host and port of server that served this file -// // const host = readQueryVariable('host', window.location.hostname); -// // let port = readQueryVariable('port', window.location.port); -// // const password = readQueryVariable('password', ''); + // const host = readQueryVariable('host', window.location.hostname); + // let port = readQueryVariable('port', window.location.port); + // const password = readQueryVariable('password', ''); -// const { vnc_url } = this.props; -// // http://117.50.12.63:43149/vnc_lite.html?password=headless -// let _ar1 = vnc_url.split('/'); -// let ipAndPort = _ar1[2].split(':') -// let passwordAr = _ar1[3].split('password=') -// const host = ipAndPort[0] -// let port = ipAndPort[1] -// const password = passwordAr[1].split('&')[0] + const { vnc_url } = this.props; + // http://117.50.12.63:43149/vnc_lite.html?password=headless + let _ar1 = vnc_url.split('/'); + let ipAndPort = _ar1[2].split(':') + let passwordAr = _ar1[3].split('password=') + const host = ipAndPort[0] + let port = ipAndPort[1] + const password = passwordAr[1].split('&')[0] -// const path = readQueryVariable('path', 'websockify'); -// // | | | | | | -// // | | | Connect | | | -// // v v v v v v -// status("Connecting"); -// // Build the websocket URL used to connect -// let url; -// if (vnc_url.indexOf("https:") != -1) { -// url = 'wss'; -// } else { -// url = 'ws'; -// } -// url += '://' + host; -// if(port) { -// url += ':' + port; -// } -// url += '/' + path; -// // Creating a new RFB object will start a new connection -// rfb = new RFB(document.getElementById('screen'), url, -// { credentials: { password: password } }); -// // Add listeners to important events from the RFB module -// rfb.addEventListener("connect", connectedToServer); -// rfb.addEventListener("disconnect", disconnectedFromServer); -// rfb.addEventListener("credentialsrequired", credentialsAreRequired); -// rfb.addEventListener("desktopname", updateDesktopName); -// // Set parameters that can be changed on an active connection -// rfb.viewOnly = readQueryVariable('view_only', false); -// rfb.scaleViewport = readQueryVariable('scale', false); -// } + const path = readQueryVariable('path', 'websockify'); + // | | | | | | + // | | | Connect | | | + // v v v v v v + status("Connecting"); + // Build the websocket URL used to connect + let url; + if (vnc_url.indexOf("https:") != -1) { + url = 'wss'; + } else { + url = 'ws'; + } + url += '://' + host; + if(port) { + url += ':' + port; + } + url += '/' + path; + // Creating a new RFB object will start a new connection + rfb = new RFB(document.getElementById('screen'), url, + { credentials: { password: password } }); + // Add listeners to important events from the RFB module + rfb.addEventListener("connect", connectedToServer); + rfb.addEventListener("disconnect", disconnectedFromServer); + rfb.addEventListener("credentialsrequired", credentialsAreRequired); + rfb.addEventListener("desktopname", updateDesktopName); + // Set parameters that can be changed on an active connection + rfb.viewOnly = readQueryVariable('view_only', false); + rfb.scaleViewport = readQueryVariable('scale', false); + } -// render() { -// const { challenge, vnc_url } = this.props + render() { + const { challenge, vnc_url } = this.props -// return ( -//
-// -//
-//
Loading
-//
Send CtrlAltDel
-//
-//
-//
-// ); -// } -// } + return ( +
+ +
+
Loading
+
Send CtrlAltDel
+
+
+
+ ); + } +} -// export default VNCDisplay; +export default VNCDisplay; diff --git a/public/react/src/modules/page/main/CodeEvaluateView.js b/public/react/src/modules/page/main/CodeEvaluateView.js index b2e83c41b..8f28a8c63 100644 --- a/public/react/src/modules/page/main/CodeEvaluateView.js +++ b/public/react/src/modules/page/main/CodeEvaluateView.js @@ -192,16 +192,23 @@ class CodeEvaluateView extends Component {
{`已经过职业认证的教师可以免金币查看隐藏测试集。`}
{`解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?`}
+
this.goToCertification()} style={{color: '#4CACFF', cursor: 'pointer', 'text-decoration': 'underline' + , 'margin-top': '12px'}}>立即认证
: - `解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?` + +
{`解锁本关所有测试集需要扣除${challenge.score*5}金币`}
+
{`确定要解锁吗?`}
+
const moreButtonsRender = () => { - return (power === 0 && user.is_teacher) ? ( - - ) : '' + return '' + // ${this.props.classes.button} + // return (power === 0 && user.is_teacher) ? ( + // + // ) : '' } testSetsComponentArray.push(
diff --git a/public/react/src/modules/page/tpiPage.css b/public/react/src/modules/page/tpiPage.css index 34274907e..4fc4e3062 100644 --- a/public/react/src/modules/page/tpiPage.css +++ b/public/react/src/modules/page/tpiPage.css @@ -229,6 +229,9 @@ body>div[role=dialog]>div { /* padding-bottom: 10px; */ } /* tpi 窗口宽度*/ +#tpi-dialog>div[role=document] { + border-radius: 10px; +} body>div[role=dialog] div[role=document] { min-width: 400px; }