温柔戏命师

文章 评论 浏览 29

温柔戏命师 2025-02-20 22:11:14

是的。但是,DBT需要一个“原因”来创建表,例如,以实现其模型之一产生的数据。 DBT不能仅仅为了创建而创建表。

好吧,严格来说,您可以通过将创建表... 放在前钩或hook hook 部分,但我想这不是您想要的,因为DBT在这里根本没有任何区别。

您可以在

{{ materialized="table" }}
select * 
from {{ source('your_source', 'existed_table_name') }}
limit 1 /* add "limit 1" if you only want the structure  */ 

将必要的连接凭据放在 profiles.yml 中,然后构建模型。在该模型表创建免费完成之前,DBT将从源表将一行从源表复制到模型表。

Yes. However, Dbt needs a "reason" to create tables, for example, to materialize the data produced by one of its models. DBT cannot create table just for the creation's sake.

Well, strictly speaking, you can do this by putting CREATE TABLE... in a pre-hook or post-hook section, but I suppose this is not what you want since dbt makes no difference here at all.

You can define your existed table in sources where you can set database, schema and table name different from the target storage space where dbt writes data. And then, define a model something like:

{{ materialized="table" }}
select * 
from {{ source('your_source', 'existed_table_name') }}
limit 1 /* add "limit 1" if you only want the structure  */ 

Put necessary connection credentials in the profiles.yml, and build the model. Dbt will copy one row from source table into model table, before that model table creation is done for free.

使用DBT创建表

温柔戏命师 2025-02-20 18:21:09

假设 infgenerator 关闭 inf 接收完成信号:

闭合 done1 导致关闭 inf> inf >,这会导致 ordone 如您所说的。

如果您关闭完成而是函数 ordone 执行嵌套完成的案例,那么ofter 完成 case,因为嵌套的完成情况没有从该功能返回。它读取完成的信号,继续循环,循环再次读取完成信号并返回。

一个未掩盖的通道没有任何数据。因此,如果您关闭一个未掩盖的通道,则任何goroutines都将通过 false 启用。任何进一步的读取尝试也将立即返回 false 。因此,关闭频道是将完成所有Goroutines广播的好方法。

Assuming infGenerator closes inf after receiving the done signal:

Closing done1 results in closing inf, which causes orDone to return as you said.

If you close done instead, the function orDone executes the nested done case, then the outer done case, simply because the nested done case did not return from the function. It reads the done signal, continues looping, and the loop reads the done signal again and returns.

An unbuffered channel does not hold any data. Thus, if you close an unbuffered channel, any goroutines blocked reading from it will be enabled with false. Any further read attempts will also immediately return false. Because of this, closing a channel is a good way to broadcast completion to all goroutines.

另一个频道内部信号的通道如何一起工作?

温柔戏命师 2025-02-20 18:19:57

如果您试图在JSON字符串中找到路径,则可以将数据倒入工具中以确定您的路径。

当您在嵌套的JS对象结构中徘徊在它们上时,Chrome Developer Console将显示属性路径,可以使用 JSON.PARSE(JSON)在必要时从JSON中解析

。 /I.SSTATIC.NET/1H3RH.PNG“ rel =” nofollow noreferrer“> “

您也可以将路径复制到剪贴板:

noreferrer“> ” [0] 替换偏移索引来迭代数组 环形。然后,您可以在其位置使用循环索引 [i] ,也可以使用 foreach 样式函数替换整个属性和索引。

另一个工具是 https://jsonpathfinder.com 您可以在其中单击GUI元素。它将为像chrome一样的路径生成JS语法。

我写了一个简单的工具,您可以在这里或 https://ggorlen.github.io/json -Dive/。将JSON字符串粘贴到Textarea中,然后单击节点将其路径复制到剪贴板。它可以选择使用括号而不是点生成Python/PHP样式索引。

/* code minified to make the tool easier to run without having to scroll */                                                         let bracketsOnly=!1,lastHighlighted={style:{}};const keyToStr=t=>!bracketsOnly&&/^[a-zA-Z_$][a-zA-Z$_\d]*$/.test(t)?`.${toHTML(t)}`:`["${toHTML(t)}"]`,pathToData=t=>`data-path="data${t.join("")}"`,htmlSpecialChars={"&":"&","<":"<",">":">",'"':""","'":"'","\t":"\\t","\r":"\\r","\n":"\\n"," ":" "},toHTML=t=>(""+t).replace(/[&<>"'\t\r\n ]/g,t=>htmlSpecialChars[t]),makeArray=(t,e)=>`\n  [<ul ${pathToData(e)}>\n    ${t.map((t,a)=>{e.push(`[${a}]`);const n=`<li ${pathToData(e)}>\n        ${pathify(t,e).trim()},\n      </li>`;return e.pop(),n}).join("")}\n  </ul>]\n`,makeObj=(t,e)=>`\n  {<ul ${pathToData(e)}>\n    ${Object.entries(t).map(([t,a])=>{e.push(keyToStr(t));const n=`<li ${pathToData(e)}>\n        "${toHTML(t)}": ${pathify(a,e).trim()},\n      </li>`;return e.pop(),n}).join("")}\n  </ul>}\n`,pathify=(t,e=[])=>Array.isArray(t)?makeArray(t,e):"object"==typeof t&&t!=null?makeObj(t,e):toHTML("string"==typeof t?`"${t}"`:t),defaultJSON='{\n  "corge": "test JSON... \\n   asdf\\t asdf",\n  "foo-bar": [\n    {"id": 42},\n    [42, {"foo": {"baz": {"ba  r<>!\\t": true, "4quux": "garply"}}}]\n  ]\n}',$=document.querySelector.bind(document),$=document.querySelectorAll.bind(document),resultEl=$("#result"),pathEl=$("#path"),tryToJSON=t=>{try{resultEl.innerHTML=pathify(JSON.parse(t)),$("#error").innerText=""}catch(t){resultEl.innerHTML="",$("#error").innerText=t}},copyToClipboard=t=>{const e=document.createElement("textarea");e.textContent=t,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)},flashAlert=(t,e=2e3)=>{const a=document.createElement("div");a.textContent=t,a.classList.add("alert"),document.body.appendChild(a),setTimeout(()=>a.remove(),e)},handleClick=t=>{t.stopPropagation(),copyToClipboard(t.target.dataset.path),flashAlert("copied!"),$("#path-out").textContent=t.target.dataset.path},handleMouseOut=t=>{lastHighlighted.style.background="transparent",pathEl.style.display="none"},handleMouseOver=t=>{pathEl.textContent=t.target.dataset.path,pathEl.style.left=`${t.pageX+30}px`,pathEl.style.top=`${t.pageY}px`,pathEl.style.display="block",lastHighlighted.style.background="transparent",(lastHighlighted=t.target.closest("li")).style.background="#0ff"},handleNewJSON=t=>{tryToJSON(t.target.value),[...$("#result *")].forEach(t=>{t.addEventListener("click",handleClick),t.addEventListener("mouseout",handleMouseOut),t.addEventListener("mouseover",handleMouseOver)})};$("textarea").addEventListener("change",handleNewJSON),$("textarea").addEventListener("keyup",handleNewJSON),$("textarea").value=defaultJSON,$("#brackets").addEventListener("change",t=>{bracketsOnly=!bracketsOnly,handleNewJSON({target:{value:$("textarea").value}})}),handleNewJSON({target:{value:defaultJSON}});
/**/                                                                                       *{box-sizing:border-box;font-family:monospace;margin:0;padding:0}html{height:100%}#path-out{background-color:#0f0;padding:.3em}body{margin:0;height:100%;position:relative;background:#f8f8f8}textarea{width:100%;height:110px;resize:vertical}#opts{background:#e8e8e8;padding:.3em}#opts label{padding:.3em}#path{background:#000;transition:all 50ms;color:#fff;padding:.2em;position:absolute;display:none}#error{margin:.5em;color:red}#result ul{list-style:none}#result li{cursor:pointer;border-left:1em solid transparent}#result li:hover{border-color:#ff0}.alert{background:#f0f;padding:.2em;position:fixed;bottom:10px;right:10px}
<!-- -->                                                                                                    <div class="wrapper"><textarea></textarea><div id="opts"><label>brackets only: <input id="brackets"type="checkbox"></label></div><div id="path-out">click a node to copy path to clipboard</div><div id="path"></div><div id="result"></div><div id="error"></div></div>

未经许可(也可以在 github ):

let bracketsOnly = false;
let lastHighlighted = {style: {}};

const keyToStr = k =>
  !bracketsOnly && /^[a-zA-Z_$][a-zA-Z$_\d]*$/.test(k) 
    ? `.${toHTML(k)}`
    : `["${toHTML(k)}"]`
;
const pathToData = p => `data-path="data${p.join("")}"`;

const htmlSpecialChars = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': """,
  "'": "'",
  "\t": "\\t",
  "\r": "\\r",
  "\n": "\\n",
  " ": " ",
};
const toHTML = x => ("" + x)
  .replace(/[&<>"'\t\r\n ]/g, m => htmlSpecialChars[m])
;

const makeArray = (x, path) => `
  [<ul ${pathToData(path)}>
    ${x.map((e, i) => {
      path.push(`[${i}]`);
      const html = `<li ${pathToData(path)}>
        ${pathify(e, path).trim()},
      </li>`;
      path.pop();
      return html;
    }).join("")}
  </ul>]
`;
const makeObj = (x, path) => `
  {<ul ${pathToData(path)}>
    ${Object.entries(x).map(([k, v]) => {
      path.push(keyToStr(k));
      const html = `<li ${pathToData(path)}>
        "${toHTML(k)}": ${pathify(v, path).trim()},
      </li>`;
      path.pop();
      return html;
    }).join("")}
  </ul>}
`;

const pathify = (x, path=[]) => {
  if (Array.isArray(x)) {
    return makeArray(x, path);
  }
  else if (typeof x === "object" && x !== null) {
    return makeObj(x, path);
  }
  
  return toHTML(typeof x === "string" ? `"${x}"` : x);
};

const defaultJSON = `{
  "corge": "test JSON... \\n   asdf\\t asdf",
  "foo-bar": [
    {"id": 42},
    [42, {"foo": {"baz": {"ba  r<>!\\t": true, "4quux": "garply"}}}]
  ]
}`;

const $ = document.querySelector.bind(document);
const $ = document.querySelectorAll.bind(document);
const resultEl = $("#result");
const pathEl = $("#path");

const tryToJSON = v => {
  try {
    resultEl.innerHTML = pathify(JSON.parse(v));
    $("#error").innerText = "";
  }
  catch (err) {
    resultEl.innerHTML = "";
    $("#error").innerText = err;
  }
};

const copyToClipboard = text => {
  const ta = document.createElement("textarea");
  ta.textContent = text;
  document.body.appendChild(ta);
  ta.select();
  document.execCommand("copy");
  document.body.removeChild(ta);
};

const flashAlert = (text, timeoutMS=2000) => {
  const alert = document.createElement("div");
  alert.textContent = text;
  alert.classList.add("alert");
  document.body.appendChild(alert);
  setTimeout(() => alert.remove(), timeoutMS);
};

const handleClick = e => {
  e.stopPropagation();
  copyToClipboard(e.target.dataset.path);
  flashAlert("copied!");
  $("#path-out").textContent = e.target.dataset.path;
};

const handleMouseOut = e => {
  lastHighlighted.style.background = "transparent";
  pathEl.style.display = "none";
};

const handleMouseOver = e => {
  pathEl.textContent = e.target.dataset.path;
  pathEl.style.left = `${e.pageX + 30}px`;
  pathEl.style.top = `${e.pageY}px`;
  pathEl.style.display = "block";
  lastHighlighted.style.background = "transparent";
  lastHighlighted = e.target.closest("li");
  lastHighlighted.style.background = "#0ff";
};

const handleNewJSON = e => {
  tryToJSON(e.target.value);
  [...$("#result *")].forEach(e => {
    e.addEventListener("click", handleClick);
    e.addEventListener("mouseout", handleMouseOut);
    e.addEventListener("mouseover", handleMouseOver);
  });
};
$("textarea").addEventListener("change", handleNewJSON);
$("textarea").addEventListener("keyup", handleNewJSON);
$("textarea").value = defaultJSON;
$("#brackets").addEventListener("change", e => {
  bracketsOnly = !bracketsOnly;
  handleNewJSON({target: {value: $("textarea").value}});
});
handleNewJSON({target: {value: defaultJSON}});
* {
  box-sizing: border-box;
  font-family: monospace;
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

#path-out {
  background-color: #0f0;
  padding: 0.3em;
}

body {
  margin: 0;
  height: 100%;
  position: relative;
  background: #f8f8f8;
}

textarea {
  width: 100%;
  height: 110px;
  resize: vertical;
}

#opts {
  background: #e8e8e8;
  padding: 0.3em;
}
#opts label {
  padding: 0.3em;
}

#path {
  background: black;
  transition: all 0.05s;
  color: white;
  padding: 0.2em;
  position: absolute;
  display: none;
}

#error {
  margin: 0.5em;
  color: red;
}

#result ul {
  list-style: none;
}

#result li {
  cursor: pointer;
  border-left: 1em solid transparent;
}
#result li:hover {
  border-color: #ff0;
}

.alert {
  background: #f0f;
  padding: 0.2em;
  position: fixed;
  bottom: 10px;
  right: 10px;
}
<div class="wrapper">
  <textarea></textarea>
  <div id="opts">
    <label>
      brackets only: <input id="brackets" type="checkbox">
    </label>
  </div>
  <div id="path-out">click a node to copy path to clipboard</div>
  <div id="path"></div>
  <div id="result"></div>
  <div id="error"></div>
</div>

这并不是要替代学习如何钓鱼,但是一旦您知道,就可以节省时间。

If you're trying to find a path in a JSON string, you can dump your data into a tool to determine the path for you.

The Chrome developer console shows property paths when you hover over them in a nested JS object structure, which can be parsed from JSON using JSON.parse(json) if necessary:

chrome console hovering an object key shows the path to get there on hover

You can also copy the path to the clipboard:

chrome console about to copy property path for object to clipboard using the context menu on a node

Once you have a path on the clipboard, you will typically want to iterate arrays by replacing the offset indexers like [0] with a loop. You can then use the loop index [i] in its place, or use a forEach style function to replace the whole property and index.

Another tool is https://jsonpathfinder.com where you can click on the GUI elements. It'll generate the JS syntax for the path to the element like Chrome.

I wrote a simple tool you can run here, or at https://ggorlen.github.io/json-dive/. Paste your JSON string into the textarea, then click the node to copy its path to your clipboard. It has an option to generate Python/PHP style indexes with brackets rather than dots.

/* code minified to make the tool easier to run without having to scroll */                                                         let bracketsOnly=!1,lastHighlighted={style:{}};const keyToStr=t=>!bracketsOnly&&/^[a-zA-Z_$][a-zA-Z$_\d]*$/.test(t)?`.${toHTML(t)}`:`["${toHTML(t)}"]`,pathToData=t=>`data-path="data${t.join("")}"`,htmlSpecialChars={"&":"&","<":"<",">":">",'"':""","'":"'","\t":"\\t","\r":"\\r","\n":"\\n"," ":" "},toHTML=t=>(""+t).replace(/[&<>"'\t\r\n ]/g,t=>htmlSpecialChars[t]),makeArray=(t,e)=>`\n  [<ul ${pathToData(e)}>\n    ${t.map((t,a)=>{e.push(`[${a}]`);const n=`<li ${pathToData(e)}>\n        ${pathify(t,e).trim()},\n      </li>`;return e.pop(),n}).join("")}\n  </ul>]\n`,makeObj=(t,e)=>`\n  {<ul ${pathToData(e)}>\n    ${Object.entries(t).map(([t,a])=>{e.push(keyToStr(t));const n=`<li ${pathToData(e)}>\n        "${toHTML(t)}": ${pathify(a,e).trim()},\n      </li>`;return e.pop(),n}).join("")}\n  </ul>}\n`,pathify=(t,e=[])=>Array.isArray(t)?makeArray(t,e):"object"==typeof t&&t!=null?makeObj(t,e):toHTML("string"==typeof t?`"${t}"`:t),defaultJSON='{\n  "corge": "test JSON... \\n   asdf\\t asdf",\n  "foo-bar": [\n    {"id": 42},\n    [42, {"foo": {"baz": {"ba  r<>!\\t": true, "4quux": "garply"}}}]\n  ]\n}',$=document.querySelector.bind(document),$=document.querySelectorAll.bind(document),resultEl=$("#result"),pathEl=$("#path"),tryToJSON=t=>{try{resultEl.innerHTML=pathify(JSON.parse(t)),$("#error").innerText=""}catch(t){resultEl.innerHTML="",$("#error").innerText=t}},copyToClipboard=t=>{const e=document.createElement("textarea");e.textContent=t,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)},flashAlert=(t,e=2e3)=>{const a=document.createElement("div");a.textContent=t,a.classList.add("alert"),document.body.appendChild(a),setTimeout(()=>a.remove(),e)},handleClick=t=>{t.stopPropagation(),copyToClipboard(t.target.dataset.path),flashAlert("copied!"),$("#path-out").textContent=t.target.dataset.path},handleMouseOut=t=>{lastHighlighted.style.background="transparent",pathEl.style.display="none"},handleMouseOver=t=>{pathEl.textContent=t.target.dataset.path,pathEl.style.left=`${t.pageX+30}px`,pathEl.style.top=`${t.pageY}px`,pathEl.style.display="block",lastHighlighted.style.background="transparent",(lastHighlighted=t.target.closest("li")).style.background="#0ff"},handleNewJSON=t=>{tryToJSON(t.target.value),[...$("#result *")].forEach(t=>{t.addEventListener("click",handleClick),t.addEventListener("mouseout",handleMouseOut),t.addEventListener("mouseover",handleMouseOver)})};$("textarea").addEventListener("change",handleNewJSON),$("textarea").addEventListener("keyup",handleNewJSON),$("textarea").value=defaultJSON,$("#brackets").addEventListener("change",t=>{bracketsOnly=!bracketsOnly,handleNewJSON({target:{value:$("textarea").value}})}),handleNewJSON({target:{value:defaultJSON}});
/**/                                                                                       *{box-sizing:border-box;font-family:monospace;margin:0;padding:0}html{height:100%}#path-out{background-color:#0f0;padding:.3em}body{margin:0;height:100%;position:relative;background:#f8f8f8}textarea{width:100%;height:110px;resize:vertical}#opts{background:#e8e8e8;padding:.3em}#opts label{padding:.3em}#path{background:#000;transition:all 50ms;color:#fff;padding:.2em;position:absolute;display:none}#error{margin:.5em;color:red}#result ul{list-style:none}#result li{cursor:pointer;border-left:1em solid transparent}#result li:hover{border-color:#ff0}.alert{background:#f0f;padding:.2em;position:fixed;bottom:10px;right:10px}
<!-- -->                                                                                                    <div class="wrapper"><textarea></textarea><div id="opts"><label>brackets only: <input id="brackets"type="checkbox"></label></div><div id="path-out">click a node to copy path to clipboard</div><div id="path"></div><div id="result"></div><div id="error"></div></div>

Unminified (also available on GitHub):

let bracketsOnly = false;
let lastHighlighted = {style: {}};

const keyToStr = k =>
  !bracketsOnly && /^[a-zA-Z_$][a-zA-Z$_\d]*$/.test(k) 
    ? `.${toHTML(k)}`
    : `["${toHTML(k)}"]`
;
const pathToData = p => `data-path="data${p.join("")}"`;

const htmlSpecialChars = {
  "&": "&",
  "<": "<",
  ">": ">",
  '"': """,
  "'": "'",
  "\t": "\\t",
  "\r": "\\r",
  "\n": "\\n",
  " ": " ",
};
const toHTML = x => ("" + x)
  .replace(/[&<>"'\t\r\n ]/g, m => htmlSpecialChars[m])
;

const makeArray = (x, path) => `
  [<ul ${pathToData(path)}>
    ${x.map((e, i) => {
      path.push(`[${i}]`);
      const html = `<li ${pathToData(path)}>
        ${pathify(e, path).trim()},
      </li>`;
      path.pop();
      return html;
    }).join("")}
  </ul>]
`;
const makeObj = (x, path) => `
  {<ul ${pathToData(path)}>
    ${Object.entries(x).map(([k, v]) => {
      path.push(keyToStr(k));
      const html = `<li ${pathToData(path)}>
        "${toHTML(k)}": ${pathify(v, path).trim()},
      </li>`;
      path.pop();
      return html;
    }).join("")}
  </ul>}
`;

const pathify = (x, path=[]) => {
  if (Array.isArray(x)) {
    return makeArray(x, path);
  }
  else if (typeof x === "object" && x !== null) {
    return makeObj(x, path);
  }
  
  return toHTML(typeof x === "string" ? `"${x}"` : x);
};

const defaultJSON = `{
  "corge": "test JSON... \\n   asdf\\t asdf",
  "foo-bar": [
    {"id": 42},
    [42, {"foo": {"baz": {"ba  r<>!\\t": true, "4quux": "garply"}}}]
  ]
}`;

const $ = document.querySelector.bind(document);
const $ = document.querySelectorAll.bind(document);
const resultEl = $("#result");
const pathEl = $("#path");

const tryToJSON = v => {
  try {
    resultEl.innerHTML = pathify(JSON.parse(v));
    $("#error").innerText = "";
  }
  catch (err) {
    resultEl.innerHTML = "";
    $("#error").innerText = err;
  }
};

const copyToClipboard = text => {
  const ta = document.createElement("textarea");
  ta.textContent = text;
  document.body.appendChild(ta);
  ta.select();
  document.execCommand("copy");
  document.body.removeChild(ta);
};

const flashAlert = (text, timeoutMS=2000) => {
  const alert = document.createElement("div");
  alert.textContent = text;
  alert.classList.add("alert");
  document.body.appendChild(alert);
  setTimeout(() => alert.remove(), timeoutMS);
};

const handleClick = e => {
  e.stopPropagation();
  copyToClipboard(e.target.dataset.path);
  flashAlert("copied!");
  $("#path-out").textContent = e.target.dataset.path;
};

const handleMouseOut = e => {
  lastHighlighted.style.background = "transparent";
  pathEl.style.display = "none";
};

const handleMouseOver = e => {
  pathEl.textContent = e.target.dataset.path;
  pathEl.style.left = `${e.pageX + 30}px`;
  pathEl.style.top = `${e.pageY}px`;
  pathEl.style.display = "block";
  lastHighlighted.style.background = "transparent";
  lastHighlighted = e.target.closest("li");
  lastHighlighted.style.background = "#0ff";
};

const handleNewJSON = e => {
  tryToJSON(e.target.value);
  [...$("#result *")].forEach(e => {
    e.addEventListener("click", handleClick);
    e.addEventListener("mouseout", handleMouseOut);
    e.addEventListener("mouseover", handleMouseOver);
  });
};
$("textarea").addEventListener("change", handleNewJSON);
$("textarea").addEventListener("keyup", handleNewJSON);
$("textarea").value = defaultJSON;
$("#brackets").addEventListener("change", e => {
  bracketsOnly = !bracketsOnly;
  handleNewJSON({target: {value: $("textarea").value}});
});
handleNewJSON({target: {value: defaultJSON}});
* {
  box-sizing: border-box;
  font-family: monospace;
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

#path-out {
  background-color: #0f0;
  padding: 0.3em;
}

body {
  margin: 0;
  height: 100%;
  position: relative;
  background: #f8f8f8;
}

textarea {
  width: 100%;
  height: 110px;
  resize: vertical;
}

#opts {
  background: #e8e8e8;
  padding: 0.3em;
}
#opts label {
  padding: 0.3em;
}

#path {
  background: black;
  transition: all 0.05s;
  color: white;
  padding: 0.2em;
  position: absolute;
  display: none;
}

#error {
  margin: 0.5em;
  color: red;
}

#result ul {
  list-style: none;
}

#result li {
  cursor: pointer;
  border-left: 1em solid transparent;
}
#result li:hover {
  border-color: #ff0;
}

.alert {
  background: #f0f;
  padding: 0.2em;
  position: fixed;
  bottom: 10px;
  right: 10px;
}
<div class="wrapper">
  <textarea></textarea>
  <div id="opts">
    <label>
      brackets only: <input id="brackets" type="checkbox">
    </label>
  </div>
  <div id="path-out">click a node to copy path to clipboard</div>
  <div id="path"></div>
  <div id="result"></div>
  <div id="error"></div>
</div>

This isn't intended as a substitute for learning how to fish but can save time once you do know.

如何访问和处理嵌套对象,数组或JSON?

温柔戏命师 2025-02-20 13:43:39

尝试:

dct = {
    -1: [2, 10, 11],
    0: [3, 6, 27, 33],
    1: [0, 5, 21],
    2: [15],
    3: [50, 113, 160, 213, 224],
}


df = pd.DataFrame({"Number": dct.keys(), "Value": dct.values()})
print(df)

打印:

   Number                     Value
0      -1               [2, 10, 11]
1       0            [3, 6, 27, 33]
2       1                [0, 5, 21]
3       2                      [15]
4       3  [50, 113, 160, 213, 224]

Try:

dct = {
    -1: [2, 10, 11],
    0: [3, 6, 27, 33],
    1: [0, 5, 21],
    2: [15],
    3: [50, 113, 160, 213, 224],
}


df = pd.DataFrame({"Number": dct.keys(), "Value": dct.values()})
print(df)

Prints:

   Number                     Value
0      -1               [2, 10, 11]
1       0            [3, 6, 27, 33]
2       1                [0, 5, 21]
3       2                      [15]
4       3  [50, 113, 160, 213, 224]

如何将印刷的控制台输出保存到Python中的Pandas DataFrame?

温柔戏命师 2025-02-20 13:19:56

核心库中没有本机NAS存储界面,但是我们提供有关如何解决 modulenorfounderror 的食谱和指南 - 查看这个话语wiki页面您可以如何解决该方法

There is no native NAS storage interface available in the core library, but we provide recipes and guidance on how you may solve the ModuleNorFoundError - check out this Discourse wiki page which dives into how you may solve that

州长:是否可以访问像NAS这样的存储,包括多台机器的县?

温柔戏命师 2025-02-20 06:11:11

问题的根本原因是名称空间。同一前缀使用了两个不同的名称空间,因此我必须从XMLNamesPaceManager添加/删除。关于我的另一个问题,@Charlieface建议对我有好处。

The root cause of the issue was namespace. Two different namespaces were used for same prefix so I had to add/remove from XmlNamespaceManager. Regarding my other concern, @charlieface suggestion working fine for me.

无法使用名称空间中的XML中元素

温柔戏命师 2025-02-18 03:22:24

Any HOW ::错误要求它包装的错误实现 std :: error ::错误:: error ::错误 没有实现该特征,因此,它又不会实现上下文扩展特征。

错误消息的这一部分暗示了这一点,尽管它有点模糊,因为它在 std :: error :: error :: error :: error

50  | pub enum Error {
    | -------------- doesn't satisfy `_: anyhow::context::ext::StdError`
    |
    = note: the following trait bounds were not satisfied:
            `psa_crypto::types::status::Error: anyhow::context::ext::StdError`
            which is required by `Result<Id, psa_crypto::types::status::Error>: anyhow::Context<Id, psa_crypto::types::status::Error>`

这似乎是 psa_crypto std :: error :: error :: error :: error :: /代码>库。可能值得提交错误要求他们实施该特征。作为解决方法,您有几个选择:

  • 因为 psa_crypto ::类型:: status :: status :: error 实施 std :: fmt :: fmt :: debug 您可以使用它来获得A 字符串错误消息: psa_crypto :: init()。map_err(| e |格式! >
  • 更漂亮的解决方案是实现确实实现错误的包装类型(及其要求, display )。

anyhow::Error requires that the error it wraps implement std::error::Error. psa_crypto::types::status::Error does not implement that trait, so in turn, it does not implement the Context extension trait.

This part of the error message hints at this, though it's a bit obscured, since it prints anyhow's internal alias for std::error::Error:

50  | pub enum Error {
    | -------------- doesn't satisfy `_: anyhow::context::ext::StdError`
    |
    = note: the following trait bounds were not satisfied:
            `psa_crypto::types::status::Error: anyhow::context::ext::StdError`
            which is required by `Result<Id, psa_crypto::types::status::Error>: anyhow::Context<Id, psa_crypto::types::status::Error>`

This seems like an oversight in the psa_crypto library. It may be worth filing a bug asking them to implement that trait. As a workaround, you have a few options:

  • Since psa_crypto::types::status::Error implements std::fmt::Debug, you can use this to get a String error message: psa_crypto::init().map_err(|e| format!("{:?}", e).context("While initializing")
  • A prettier solution would be to implement a wrapper type that does implement Error (and its requirement, Display).

RUST:为什么我可以使用此库中的上下文来使用::上下文?

温柔戏命师 2025-02-17 19:13:23

写和阅读许可

chown -R www-data:www-data /var/www/dicrctoy 
chmod -R 775 /var/www/dicrctoy

to write and read permission

chown -R www-data:www-data /var/www/dicrctoy 
chmod -R 775 /var/www/dicrctoy

fopen()在调试会话中正常工作,但是当我通过浏览器调用文件时,没有工作

温柔戏命师 2025-02-17 15:51:42

这应该可以完成这项工作,它将在当前幻灯片视频的末尾播放下一张幻灯片,然后循环回到上一个幻灯片视频结束事件的第一个幻灯片,无论您拥有多少个视频,都会有效地循环所有幻灯片。

const getPlayerInstance = function (tindex) {
  const playerDom = $('video-js')[tindex];
  const id = $(playerDom).attr('id');
  return videojs.getPlayer(id);
};
$(document).ready(function () {
  const swiper = new Swiper(".mySwiper", {
    autoplay: false,
    spaceBetween: 30,
    centeredSlides: true,
    pagination: {
      el: ".swiper-pagination",
      clickable: true,
    },
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
  });
  for (i = 0; i < $("video-js").length; i++) {
    const tplayer = getPlayerInstance(i);
    if (i > 0) {
      tplayer.currentTime(0);
      tplayer.pause();
    }
    tplayer.on('ended', function () {
      if ((swiper.slides.length - 1) === swiper.activeIndex) {
        swiper.slideTo(0);       
      } else {
        swiper.slideNext();   
      }
    })
  }
  swiper.on('slideChange', function (e) {
    const activePlayer = getPlayerInstance(swiper.activeIndex);
    activePlayer.currentTime(0);
    activePlayer.play();
  })
})
.swiper-container {
  width: 100%;
  height: 100vh;
}

.swiper-slide {
  overflow: hidden;
}

video-js {
  margin-left: calc((100vw - (100vh * 1.7)) / 2);
  margin-right: calc((100vw - (100vh * 1.7)) / 2);
  min-height: 100vh;
  min-width: 100vw;
}

@media (min-aspect-ratio: 16/9) {
  video-js {
    margin-left: 0;
  }
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper mySwiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <video-js
        id="overlayVideo0"
        class="overlayVideo"
        data-account="1752604059001"
        data-player="default"
        data-embed="default"
        controls=""
        data-video-id="4029697544001"
        data-playlist-id=""
        data-application-id=""
        data-object-fit="cover"
        autoplay
        muted
        playsinline
      >
      </video-js>
      <script src="https://players.brightcove.net/1752604059001/default_default/index.min.js"></script>
    </div>
    <div class="swiper-slide">
      <video-js
        id="overlayVideo1"
        class="overlayVideo"
        data-account="6269594386001"
        data-player="oHG2GzKTGk"
        data-embed="default"
        controls=""
        data-video-id="6304418462001"
        data-playlist-id=""
        data-application-id=""
        data-object-fit="cover"
        autoplay
        muted
        playsinline
      >
      </video-js>
      <script src="https://players.brightcove.net/6269594386001/oHG2GzKTGk_default/index.min.js"></script>
    </div>
  </div>
  <div class="swiper-button-next"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-pagination"></div>
</div>

我希望这会有所帮助

This should do the job, It will play the next slide at the end of the current slide video and then loop back to the first slide on the last slide video end event effectively always looping all the slides regardless of how many videos you have.

https://codepen.io/ptahume/pen/wvmporW?editors=1111

const getPlayerInstance = function (tindex) {
  const playerDom = $('video-js')[tindex];
  const id = $(playerDom).attr('id');
  return videojs.getPlayer(id);
};
$(document).ready(function () {
  const swiper = new Swiper(".mySwiper", {
    autoplay: false,
    spaceBetween: 30,
    centeredSlides: true,
    pagination: {
      el: ".swiper-pagination",
      clickable: true,
    },
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
  });
  for (i = 0; i < $("video-js").length; i++) {
    const tplayer = getPlayerInstance(i);
    if (i > 0) {
      tplayer.currentTime(0);
      tplayer.pause();
    }
    tplayer.on('ended', function () {
      if ((swiper.slides.length - 1) === swiper.activeIndex) {
        swiper.slideTo(0);       
      } else {
        swiper.slideNext();   
      }
    })
  }
  swiper.on('slideChange', function (e) {
    const activePlayer = getPlayerInstance(swiper.activeIndex);
    activePlayer.currentTime(0);
    activePlayer.play();
  })
})
.swiper-container {
  width: 100%;
  height: 100vh;
}

.swiper-slide {
  overflow: hidden;
}

video-js {
  margin-left: calc((100vw - (100vh * 1.7)) / 2);
  margin-right: calc((100vw - (100vh * 1.7)) / 2);
  min-height: 100vh;
  min-width: 100vw;
}

@media (min-aspect-ratio: 16/9) {
  video-js {
    margin-left: 0;
  }
}
<link href="https://unpkg.com/swiper/swiper-bundle.min.css" rel="stylesheet"/>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<div class="swiper mySwiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <video-js
        id="overlayVideo0"
        class="overlayVideo"
        data-account="1752604059001"
        data-player="default"
        data-embed="default"
        controls=""
        data-video-id="4029697544001"
        data-playlist-id=""
        data-application-id=""
        data-object-fit="cover"
        autoplay
        muted
        playsinline
      >
      </video-js>
      <script src="https://players.brightcove.net/1752604059001/default_default/index.min.js"></script>
    </div>
    <div class="swiper-slide">
      <video-js
        id="overlayVideo1"
        class="overlayVideo"
        data-account="6269594386001"
        data-player="oHG2GzKTGk"
        data-embed="default"
        controls=""
        data-video-id="6304418462001"
        data-playlist-id=""
        data-application-id=""
        data-object-fit="cover"
        autoplay
        muted
        playsinline
      >
      </video-js>
      <script src="https://players.brightcove.net/6269594386001/oHG2GzKTGk_default/index.min.js"></script>
    </div>
  </div>
  <div class="swiper-button-next"></div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-pagination"></div>
</div>

I hope this helps

根据视频播放和暂停事件在刀刀容器中停止并启动自动播放

温柔戏命师 2025-02-17 13:27:01

您不能从Userstore类中呼叫导航,也不应该在登录名中称其为

function handleSubmit() {
        userStore
           .login(info)
           .then(() => navigate('/restaurant'))
           .catch(error => setError('Invalid Email or Password'));
}

另一种方法是通过回调

function handleSubmit() {
        userStore
           .login(info, () => navigate('/restaurant'))
           .catch(error => setError('Invalid Email or Password'));
}

// UserStore class

//...
login = async (creds: UserFormValues, callback) => {
    try {
        const user = await agent.Account.login(creds);
        store.commonStore.setToken(user.token);
        runInAction(() => this.user = user);
        callback && callback()
        console.log(user);
    } catch (error) {
        throw error;
    }
}
//...

You cannot call navigate from UserStore class, and you shouldn't, better to call it inside LoginForm

function handleSubmit() {
        userStore
           .login(info)
           .then(() => navigate('/restaurant'))
           .catch(error => setError('Invalid Email or Password'));
}

Another approach is to pass a callback

function handleSubmit() {
        userStore
           .login(info, () => navigate('/restaurant'))
           .catch(error => setError('Invalid Email or Password'));
}

// UserStore class

//...
login = async (creds: UserFormValues, callback) => {
    try {
        const user = await agent.Account.login(creds);
        store.commonStore.setToken(user.token);
        runInAction(() => this.user = user);
        callback && callback()
        console.log(user);
    } catch (error) {
        throw error;
    }
}
//...

在类中调用功能组件的方法

温柔戏命师 2025-02-17 12:41:32
final myBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.grey[400], // You can change the color of the bottom border here
    width: 1.0, // Customize the width of the border
  ),
);

final myFocusedBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.blue, // Customize the color of the bottom border when the field is focused
    width: 2.0, // Customize the width of the border
  ),
);

final myEnabledBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.grey[400], // Customize the color of the bottom border when the field is enabled
    width: 1.0, // Customize the width of the border
  ),
);

TextFormField(
  decoration: InputDecoration(
    labelText: 'Enter your text', // Optional label text
    labelStyle: TextStyle(color: Colors.grey[400]), // Optional label style
    enabledBorder: myEnabledBorder,
    focusedBorder: myFocusedBorder,
    border: myBorder,
  ),
)

这仅适用于边界底部

final myBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.grey[400], // You can change the color of the bottom border here
    width: 1.0, // Customize the width of the border
  ),
);

final myFocusedBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.blue, // Customize the color of the bottom border when the field is focused
    width: 2.0, // Customize the width of the border
  ),
);

final myEnabledBorder = UnderlineInputBorder(
  borderSide: BorderSide(
    color: Colors.grey[400], // Customize the color of the bottom border when the field is enabled
    width: 1.0, // Customize the width of the border
  ),
);

TextFormField(
  decoration: InputDecoration(
    labelText: 'Enter your text', // Optional label text
    labelStyle: TextStyle(color: Colors.grey[400]), // Optional label style
    enabledBorder: myEnabledBorder,
    focusedBorder: myFocusedBorder,
    border: myBorder,
  ),
)

This works for border bottom only

如何用颤音在文本文字上进行仅侧面边界?

温柔戏命师 2025-02-17 12:21:29

我安装了Visual Studio代码,并通过将GraphViz添加为扩展名,现在我可以编写代码并获取所需的图形!

I installed Visual Studio code, and by adding graphviz as extension, now I can write my code and get the graph I wanted!

GraphViz _安装和使用说明

温柔戏命师 2025-02-17 06:25:41

如果我很好地了解逻辑,这看起来像是一个扩展的比较:

纯Python

l = [5,1,3,6]
out = [sum(l[i]>x for x in l[:i]) for i in range(len(l))]

pandas

l = [5,1,3,6]
s = pd.Series(l)

out = s.expanding().apply(lambda x: sum(x.iloc[:-1].le(x.iloc[-1]))).astype(int)
out.tolist()

numpy:

l = [5,1,3,6]
a = np.array(l)

out = np.tril(a[:,None]>a).sum(1)
out.tolist()

output: [0、0、1、3]

If I understand well the logic, this looks like an expanding comparison:

pure python

l = [5,1,3,6]
out = [sum(l[i]>x for x in l[:i]) for i in range(len(l))]

pandas

l = [5,1,3,6]
s = pd.Series(l)

out = s.expanding().apply(lambda x: sum(x.iloc[:-1].le(x.iloc[-1]))).astype(int)
out.tolist()

numpy:

l = [5,1,3,6]
a = np.array(l)

out = np.tril(a[:,None]>a).sum(1)
out.tolist()

output: [0, 0, 1, 3]

当前值是最近时期的最大值

温柔戏命师 2025-02-17 05:24:44

如果您使用 - expose-gc flag启动节点进程,则可以调用 global.gc()迫使节点运行垃圾收集。请记住,您的节点应用程序中的所有其他执行均已暂停,直到GC完成为止,因此不要经常使用它,否则会影响性能。

您可能需要在代码中拨打GC调用时包括一张检查,这样,如果没有标志的节点运行,则情况并不糟糕:

if (global.gc) {
    global.gc();
} else {
    console.log('Garbage collection unavailable.  Pass --expose-gc '
      + 'when launching node to enable forced garbage collection.');
}

If you launch the node process with the --expose-gc flag, you can then call global.gc() to force node to run garbage collection. Keep in mind that all other execution within your node app is paused until GC completes, so don't use it too often or it will affect performance.

You might want to include a check when making GC calls from within your code so things don't go bad if node was run without the flag:

if (global.gc) {
    global.gc();
} else {
    console.log('Garbage collection unavailable.  Pass --expose-gc '
      + 'when launching node to enable forced garbage collection.');
}

如何要求Node.js中的垃圾收集器运行?

温柔戏命师 2025-02-17 05:09:33

如果将输出输送到文本文件,您会发现它确实确实打印了3。但是,它仅每100 ms大约打印一次,而其他两个过程则连续打印,因此您可能不会在控制台中看到它。

If you pipe the output to a text file, you'll find that it does indeed print 3. However, it only prints roughly every 100 ms whereas the other two processes print continuously so you might not see it in the console.

Python过程阻止主线程

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文