{"id":1191,"date":"2024-04-25T03:31:28","date_gmt":"2024-04-25T03:31:28","guid":{"rendered":"https:\/\/www.nicekj.com\/?p=1191"},"modified":"2024-04-25T03:31:43","modified_gmt":"2024-04-25T03:31:43","slug":"aixieceshiyongli","status":"publish","type":"post","link":"https:\/\/www.nicekj.com\/aixieceshiyongli.html","title":{"rendered":"AI\u5199\u6d4b\u8bd5\u7528\u4f8b"},"content":{"rendered":"<h2 data-id=\"heading-0\">\u4e00\u3001\u7528ChatGPT\u76f4\u63a5\u751f\u6210\u7684\u6d4b\u8bd5\u7528\u4f8b<\/h2>\n<p>\u8981\u5199\u6d4b\u8bd5\uff0c\u6211\u4eec\u8981\u5148\u6709\u4e00\u4e2a\u7a0b\u5e8f\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u4e2a\u9898\u76ee\u672c\u8eab\u5c31\u5728AI\u7684\u8bad\u7ec3\u6570\u636e\u96c6\u91cc\u9762\uff0c\u5b83\u76f4\u63a5\u77e5\u9053\u7b54\u6848\u3002<\/p>\n<p>\u6211\u4eec\u7528\u4e00\u4e2a\u6709\u610f\u601d\u7684\u5c0f\u9898\u76ee\uff0c\u4e5f\u5c31\u662f\u8ba9Python\u6839\u636e\u6211\u4eec\u8f93\u5165\u7684\u4e00\u4e2a\u6574\u6570\u4ee3\u8868\u7684\u5929\u6570\uff0c\u683c\u5f0f\u5316\u6210\u4e00\u6bb5\u81ea\u7136\u8bed\u8a00\u63cf\u8ff0\u7684\u65f6\u95f4\u3002\u6761\u4ef6\u5b9a\u4e49\uff1a1\u4e2a\u661f\u671f\u662f7\u5929\uff0c1\u4e2a\u6708\u662f30\u5929\uff0c1\u5e74\u662f365\u5929\u3002\u6bd4\u5982\uff0c\u8f93\u51651\u5c31\u8fd4\u56de1d\uff0c\u8f93\u51658\u5c31\u8fd4\u56de1w1d\uff0c\u8f93\u516532\u5c31\u8fd4\u56de1m2d\uff0c\u8f93\u5165375\u5c31\u8fd4\u56de1y1w3d\u3002<\/p>\n<p>\u9700\u6c42\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">\u7528<span class=\"hljs-title class_\">Python<\/span>\u5199\u4e00\u4e2a\u51fd\u6570\uff0c\u8fdb\u884c\u65f6\u95f4\u683c\u5f0f\u5316\u8f93\u51fa\uff0c\u6761\u4ef6\u5b9a\u4e49\u4e3a<span class=\"hljs-number\">1<\/span>\u4e2a\u661f\u671f\u662f<span class=\"hljs-number\">7<\/span>\u5929\uff0c<span class=\"hljs-number\">1<\/span>\u4e2a\u6708\u662f<span class=\"hljs-number\">30<\/span>\u5929\uff0c<span class=\"hljs-number\">1<\/span>\u5e74\u662f<span class=\"hljs-number\">365<\/span>\u5929\u3002\u6bd4\u5982\uff1a<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">\u8f93\u5165  \u8f93\u51fa<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\"><span class=\"hljs-number\">1<\/span>     1d<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\"><span class=\"hljs-number\">8<\/span>     1w1d<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\"><span class=\"hljs-number\">61<\/span>    2m1d<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\"><span class=\"hljs-number\">375<\/span>   1y1w3d<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">\u8981\u6c42\u4ec5\u9700\u8981\u683c\u5f0f\u5316\u5230\u5e74(?y?m?w?d)\uff0c\u5373\u53ef<\/span>\n<\/code><\/pre>\n<p>\u6211\u4eec\u76f4\u63a5\u8ba9ChatGPT\u628a\u7a0b\u5e8f\u5199\u597d\u5982\u4e0b\uff1a<\/p>\n<p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.nicekj.com\/wp-content\/uploads\/replace\/d536736d2d96ecc98ddb204c05fc6abc.png\" alt=\"image.png\" \/><\/figure>\n<\/p>\n<p>\u65e2\u7136ChatGPT\u53ef\u4ee5\u5199\u4ee3\u7801\uff0c\u81ea\u7136\u4e5f\u53ef\u4ee5\u8ba9\u5b83\u5e2e\u6211\u4eec\u628a\u5355\u5143\u6d4b\u8bd5\u4e5f\u5199\u597d\uff0c\u5982\u4e0b\uff1a<\/p>\n<p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.nicekj.com\/wp-content\/uploads\/replace\/f5650a59fa0d5da60e77c7d6eb5d6c4f.png\" alt=\"image.png\" \/><\/figure>\n<\/p>\n<p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.nicekj.com\/wp-content\/uploads\/replace\/9a894ab87b2c2dfdd91e5dbb621e5c47.png\" alt=\"image.png\" \/><\/figure>\n<\/p>\n<p>\u8fd9\u4e2a\u6d4b\u8bd5\u7528\u4f8b\u8986\u76d6\u7684\u573a\u666f\u5176\u5b9e\u5df2\u7ecf\u5f88\u5168\u9762\u4e86\uff0c\u65e2\u5305\u542b\u4e86\u57fa\u672c\u7684\u529f\u80fd\u9a8c\u8bc1\u6d4b\u8bd5\u7528\u4f8b\uff0c\u4e5f\u5305\u542b\u4e86\u4e00\u4e9b\u5f02\u5e38\u7684\u6d4b\u8bd5\u7528\u4f8b\u3002<\/p>\n<h2 data-id=\"heading-1\">\u4e8c\u3001\u57fa\u4e8eOpenai\u63a5\u53e3\u8fdb\u884c\u8fc7\u7a0b\u9a8c\u8bc1<\/h2>\n<h3 data-id=\"heading-2\">2.1\u3001\u5206\u89e3\u6b65\u9aa4\u5199Prompts<\/h3>\n<p>OpenAI\u7684\u793a\u4f8b\u7ed9\u51fa\u4e86\u5f88\u597d\u7684\u601d\u8def\uff0c\u90a3\u5c31\u662f\u628a\u95ee\u9898\u62c6\u5206\u6210\u591a\u4e2a\u6b65\u9aa4\u3002<\/p>\n<ul>\n<li>\u628a\u4ee3\u7801\u4ea4\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u8ba9\u5927\u8bed\u8a00\u6a21\u578b\u89e3\u91ca\u4e00\u4e0b\uff0c\u8fd9\u4e2a\u4ee3\u7801\u662f\u5728\u5e72\u4ec0\u4e48\u3002<\/li>\n<li>\u628a\u4ee3\u7801\u548c\u4ee3\u7801\u7684\u89e3\u91ca\u4e00\u8d77\u4ea4\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u8ba9\u5927\u8bed\u8a00\u6a21\u578b\u89c4\u5212\u4e00\u4e0b\uff0c\u9488\u5bf9\u8fd9\u4e2a\u4ee3\u7801\u903b\u8f91\uff0c\u6211\u4eec\u5230\u5e95\u8981\u5199\u54ea\u51e0\u4e2aTestCase\u3002\u5982\u679c\u6570\u91cf\u592a\u5c11\uff0c\u53ef\u4ee5\u91cd\u590d\u8ba9AI\u591a\u751f\u6210\u51e0\u4e2aTestCase\u3002<\/li>\n<li>\u9488\u5bf9TestCase\u7684\u8be6\u7ec6\u63cf\u8ff0\uff0c\u518d\u63d0\u4ea4\u7ed9\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u8ba9\u5b83\u6839\u636e\u8fd9\u4e9b\u63cf\u8ff0\u751f\u6210\u5177\u4f53\u7684\u6d4b\u8bd5\u4ee3\u7801\u3002\u5bf9\u4e8e\u751f\u6210\u7684\u4ee3\u7801\uff0c\u6211\u4eec\u8fd8\u8981\u8fdb\u884c\u4e00\u6b21\u8bed\u6cd5\u68c0\u67e5\uff0c\u5982\u679c\u8bed\u6cd5\u68c0\u67e5\u90fd\u6ca1\u6cd5\u901a\u8fc7\uff0c\u6211\u4eec\u5c31\u8ba9AI\u91cd\u65b0\u518d\u751f\u6210\u4e00\u4e0b\u3002<\/li>\n<\/ul>\n<h3 data-id=\"heading-3\">2.2\u3001\u8bf7AI\u89e3\u91ca\u8981\u6d4b\u8bd5\u7684\u4ee3\u7801<\/h3>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">ini<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-ini code-block-extension-codeShowNum\" lang=\"ini\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">import openai<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">def gpt35(prompt, <span class=\"hljs-attr\">model<\/span>=<span class=\"hljs-string\">\"text-davinci-002\"<\/span>, temperature=<span class=\"hljs-number\">0.4<\/span>, max_tokens=<span class=\"hljs-number\">1000<\/span>,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">          <span class=\"hljs-attr\">top_p<\/span>=<span class=\"hljs-number\">1<\/span>, stop=[<span class=\"hljs-string\">\"nn\"<\/span>, <span class=\"hljs-string\">\"ntn\"<\/span>, <span class=\"hljs-string\">\"n    n\"<\/span>]):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">    <span class=\"hljs-attr\">response<\/span> = openai.Completion.create(<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">        <span class=\"hljs-attr\">model<\/span>=model,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">        <span class=\"hljs-attr\">prompt<\/span>=prompt,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">        <span class=\"hljs-attr\">temperature<\/span>=temperature,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">        <span class=\"hljs-attr\">max_tokens<\/span>=max_tokens,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">        <span class=\"hljs-attr\">top_p<\/span>=top_p,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">        <span class=\"hljs-attr\">stop<\/span>=stop<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">    )<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\">    <span class=\"hljs-attr\">message<\/span> = response[<span class=\"hljs-string\">\"choices\"<\/span>][<span class=\"hljs-number\">0<\/span>][<span class=\"hljs-string\">\"text\"<\/span>]<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">    return message<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\"><span class=\"hljs-attr\">code<\/span> = <span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\">def format_time(days):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">    years, days = divmod(days, 365)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">    months, days = divmod(days, 30)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"22\">    weeks, days = divmod(days, 7)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"23\">    time_str = \"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"24\">    if years &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"25\">        time_str += str(years) + \"y\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"26\">    if months &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"27\">        time_str += str(months) + \"m\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"28\">    if weeks &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"29\">        time_str += str(weeks) + \"w\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"30\">    if days &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"31\">        time_str += str(days) + \"d\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"32\">    return time_str<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"33\">\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"34\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"35\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"36\">def explain_code(function_to_test, <span class=\"hljs-attr\">unit_test_package<\/span>=<span class=\"hljs-string\">\"pytest\"<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"37\">    <span class=\"hljs-attr\">prompt<\/span> = f<span class=\"hljs-string\">\"\"\"\"# How to write great unit tests with {unit_test_package}<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"38\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"39\">In this advanced tutorial for experts, we'll use Python 3.8 and `{unit_test_package}` to write a suite of unit tests to verify the behavior of the following function.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"40\">```python<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"41\">{function_to_test}<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"42\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"43\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"44\">Before writing any unit tests, let's review what each element of the function is doing exactly and what the author's intentions may have been.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"45\">- First,\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"46\">    <span class=\"hljs-attr\">response<\/span> = gpt35(prompt)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"47\">    return response, prompt<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"48\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"49\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"50\">code_explaination, <span class=\"hljs-attr\">prompt_to_explain_code<\/span> = explain_code(code)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"51\">print(code_explaination)<\/span>\n<\/code><\/pre>\n<p>\u9996\u5148\u5b9a\u4e49\u4e86\u4e00\u4e2agpt35\u7684\u51fd\u6570\uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u4f5c\u7528\u5982\u4e0b\uff1a<\/p>\n<ol>\n<li>\u4f7f\u7528 text-davinci-002 \u6a21\u578b\uff0c\u8fd9\u662f\u4e00\u4e2a\u901a\u8fc7\u76d1\u7763\u5b66\u4e60\u5fae\u8c03\u7684\u751f\u6210\u6587\u672c\u7684\u6a21\u578b\uff0c\u5e0c\u671b\u751f\u6210\u76ee\u6807\u660e\u786e\u7684\u6587\u672c\u4ee3\u7801\u89e3\u91ca\u3002<\/li>\n<li>\u5bf9 stop \u505a\u4e86\u7279\u6b8a\u7684\u8bbe\u7f6e\uff0c\u53ea\u8981\u8fde\u7eed\u4e24\u4e2a\u6362\u884c\u6216\u8005\u7c7b\u4f3c\u8fde\u7eed\u4e24\u4e2a\u6362\u884c\u7684\u60c5\u51b5\u51fa\u73b0\uff0c\u5c31\u4e2d\u6b62\u6570\u636e\u7684\u751f\u6210\uff0c\u907f\u514d\u6a21\u578b\u4e00\u53e3\u6c14\u8fde\u6d4b\u8bd5\u4ee3\u7801\u4e5f\u751f\u6210\u51fa\u6765\u3002<\/li>\n<\/ol>\n<p>\u7136\u540e\uff0c\u901a\u8fc7\u4e00\u7ec4\u7cbe\u5fc3\u8bbe\u8ba1\u7684\u63d0\u793a\u8bed\uff0c\u8ba9GPT\u6a21\u578b\u4e3a\u6211\u4eec\u6765\u89e3\u91ca\u4ee3\u7801\u3002<\/p>\n<ul>\n<li>\u6307\u5b9a\u4f7f\u7528pytest\u7684\u6d4b\u8bd5\u5305\u3002<\/li>\n<li>\u628a\u5bf9\u5e94\u7684\u6d4b\u8bd5\u4ee3\u7801\u63d0\u4f9b\u7ed9GPT\u6a21\u578b\u3002<\/li>\n<li>\u8ba9AI\u56de\u7b54\uff0c\u8981\u7cbe\u786e\u63cf\u8ff0\u4ee3\u7801\u505a\u4e86\u4ec0\u4e48\u3002<\/li>\n<li>\u6700\u540e\u7528 \u201c-First\u201d \u5f00\u5934\uff0c\u5f15\u5bfcGPT\u6a21\u578b\uff0c\u9010\u6b65\u5206\u884c\u63cf\u8ff0\u8981\u6d4b\u8bd5\u7684\u4ee3\u7801\u3002<\/li>\n<\/ul>\n<p>\u8f93\u51fa\u7ed3\u679c\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\"> the <span class=\"hljs-keyword\">function<\/span> takes an integer value representing days <span class=\"hljs-keyword\">as<\/span> its sole argument.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">- <span class=\"hljs-title class_\">Next<\/span>, the <span class=\"hljs-string\">`divmod`<\/span> <span class=\"hljs-keyword\">function<\/span> is used to calculate the number <span class=\"hljs-keyword\">of<\/span> years and days, the number <span class=\"hljs-keyword\">of<\/span> months and days, and the number <span class=\"hljs-keyword\">of<\/span> weeks and days.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">- <span class=\"hljs-title class_\">Finally<\/span>, a string is built up and returned that contains the number <span class=\"hljs-keyword\">of<\/span> years, months, weeks, and days.<\/span>\n<\/code><\/pre>\n<h3 data-id=\"heading-4\">2.3\u3001\u8ba9AI\u6839\u636e\u4ee3\u7801\u89e3\u91ca\u5236\u5b9a\u6d4b\u8bd5\u8ba1\u5212<\/h3>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">ini<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-ini code-block-extension-codeShowNum\" lang=\"ini\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">def generate_a_test_plan(full_code_explaination, <span class=\"hljs-attr\">unit_test_package<\/span>=<span class=\"hljs-string\">\"pytest\"<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    <span class=\"hljs-attr\">prompt_to_explain_a_plan<\/span> = f<span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">A good unit test suite should aim to:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">- Test the function's behavior for a wide range of possible inputs<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">- Test edge cases that the author may not have foreseen<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">- Take advantage of the features of `{unit_test_package}` to make the tests easy to write and maintain<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">- Be easy to read and understand, with clean code and descriptive names<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">- Be deterministic, so that the tests always pass or fail in the same way<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">`{unit_test_package}` has many convenient features that make it easy to write and maintain unit tests. We'll use them to write unit tests for the function above.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">For this particular function, we'll want our unit tests to handle the following diverse scenarios (and under each scenario, we include a few examples as sub-bullets):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\">-\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">    <span class=\"hljs-attr\">prompt<\/span> = full_code_explaination+prompt_to_explain_a_plan<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">    <span class=\"hljs-attr\">response<\/span> = gpt35(prompt)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\">    return response, prompt<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">test_plan, <span class=\"hljs-attr\">prompt_to_get_test_plan<\/span> = generate_a_test_plan(prompt_to_explain_code+code_explaination)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">print(test_plan)<\/span>\n<\/code><\/pre>\n<p>\u9488\u5bf9\u751f\u6210\u7684\u6d4b\u8bd5\u8ba1\u5212\uff0c\u5bf9AI\u5236\u5b9a\u4e86\u51e0\u70b9\u8981\u6c42\uff1a<\/p>\n<ul>\n<li>\u6d4b\u8bd5\u7528\u4f8b\u8981\u8986\u76d6\u66f4\u5e7f\u7684\u8303\u56f4\u3002<\/li>\n<li>\u6d4b\u8bd5\u7528\u4f8b\u7684\u8fb9\u754c\u8981\u6d89\u53ca\u5230\u4f5c\u8005\u65e0\u6cd5\u60f3\u5230\u7684\u573a\u666f\u3002<\/li>\n<li>\u5145\u5206\u5229\u7528pytest\u7684\u7279\u6027\u3002<\/li>\n<li>\u786e\u4fdd\u6d4b\u8bd5\u7528\u4f8b\u7b80\u6d01\u3001\u6613\u7406\u89e3\u3002<\/li>\n<li>\u6d4b\u8bd5\u7528\u4f8b\u7684\u7ed3\u679c\u662f\u786e\u5b9a\u7684\uff0c\u8981\u4e48\u6210\u529f\u3001\u8981\u4e48\u5931\u8d25\u3002<\/li>\n<\/ul>\n<p>\u8f93\u51fa\u7ed3\u679c\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\"> <span class=\"hljs-title class_\">Normal<\/span> <span class=\"hljs-attr\">inputs<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    - <span class=\"hljs-string\">`days`<\/span> is a positive integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">    - <span class=\"hljs-string\">`days`<\/span> is <span class=\"hljs-number\">0<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">- <span class=\"hljs-title class_\">Edge<\/span> <span class=\"hljs-attr\">cases<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">    - <span class=\"hljs-string\">`days`<\/span> is a negative integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">    - <span class=\"hljs-string\">`days`<\/span> is a float<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">    - <span class=\"hljs-string\">`days`<\/span> is a string<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">- <span class=\"hljs-title class_\">Invalid<\/span> <span class=\"hljs-attr\">inputs<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">    - <span class=\"hljs-string\">`days`<\/span> is <span class=\"hljs-string\">`None`<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">    - <span class=\"hljs-string\">`days`<\/span> is a list<\/span>\n<\/code><\/pre>\n<h3 data-id=\"heading-5\">2.4\u3001\u6839\u636e\u6d4b\u8bd5\u8ba1\u5212\u751f\u6210\u6d4b\u8bd5\u4ee3\u7801<\/h3>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">ini<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-ini code-block-extension-codeShowNum\" lang=\"ini\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">def generate_test_cases(function_to_test, <span class=\"hljs-attr\">unit_test_package<\/span>=<span class=\"hljs-string\">\"pytest\"<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    <span class=\"hljs-attr\">starter_comment<\/span> = <span class=\"hljs-string\">\"Below, each test case is represented by a tuple passed to the @pytest.mark.parametrize decorator\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">    <span class=\"hljs-attr\">prompt_to_generate_the_unit_test<\/span> = f<span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">Before going into the individual tests, let's first look at the complete suite of unit tests as a cohesive whole. We've added helpful comments to explain what each line does.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">```python<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">import {unit_test_package}  # used for our unit tests<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">{function_to_test}<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">#{starter_comment}\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">    <span class=\"hljs-attr\">full_unit_test_prompt<\/span> = prompt_to_explain_code + code_explaination + test_plan + prompt_to_generate_the_unit_test<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">    return gpt35(<span class=\"hljs-attr\">model<\/span>=<span class=\"hljs-string\">\"text-davinci-003\"<\/span>, prompt=full_unit_test_prompt, stop=<span class=\"hljs-string\">\"```\"<\/span>), prompt_to_generate_the_unit_test<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">unit_test_response, <span class=\"hljs-attr\">prompt_to_generate_the_unit_test<\/span> = generate_test_cases(code)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\">print(unit_test_response)<\/span>\n<\/code><\/pre>\n<p>\u8f93\u51fa\u7ed3\u679c\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">@pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-title function_\">parametrize<\/span>(<span class=\"hljs-string\">\"days, expected\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    (<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">\"1d\"<\/span>),  # normal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">    (<span class=\"hljs-number\">7<\/span>, <span class=\"hljs-string\">\"1w\"<\/span>),  # normal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">    (<span class=\"hljs-number\">30<\/span>, <span class=\"hljs-string\">\"1m\"<\/span>),  # normal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">    (<span class=\"hljs-number\">365<\/span>, <span class=\"hljs-string\">\"1y\"<\/span>),  # normal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">    (<span class=\"hljs-number\">731<\/span>, <span class=\"hljs-string\">\"2y\"<\/span>),  # normal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">    (-<span class=\"hljs-number\">1<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">ValueError<\/span>)),  # abnormal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">    (<span class=\"hljs-number\">0<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">ValueError<\/span>)),  # abnormal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">    (<span class=\"hljs-number\">1.5<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">TypeError<\/span>)),  # abnormal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">    (<span class=\"hljs-string\">\"1\"<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">TypeError<\/span>)),  # abnormal input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">def <span class=\"hljs-title function_\">test_format_time<\/span>(days, expected):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">    <span class=\"hljs-string\">\"\"<\/span><span class=\"hljs-string\">\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\">    Test the format_time() function.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">    \"<span class=\"hljs-string\">\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title function_\">isinstance<\/span>(expected, type):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\">        # check that the expected result is a type, i.<span class=\"hljs-property\">e<\/span>. an exception<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\">        <span class=\"hljs-keyword\">with<\/span> pytest.<span class=\"hljs-title function_\">raises<\/span>(expected):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\">            # <span class=\"hljs-keyword\">if<\/span> so, check that the <span class=\"hljs-keyword\">function<\/span> raises the expected exception<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">            <span class=\"hljs-title function_\">format_time<\/span>(days)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">    <span class=\"hljs-attr\">else<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"22\">        # otherwise, check that the <span class=\"hljs-keyword\">function<\/span> returns the expected value<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"23\">        assert <span class=\"hljs-title function_\">format_time<\/span>(days) == expected<\/span>\n<\/code><\/pre>\n<h3 data-id=\"heading-6\">2.5\u3001\u901a\u8fc7AST\u5e93\u8fdb\u884c\u8bed\u6cd5\u68c0\u67e5<\/h3>\n<p>\u6700\u540e\u6211\u4eec\u6700\u597d\u8fd8\u662f\u8981\u518d\u68c0\u67e5\u4e00\u4e0b\u751f\u6210\u7684\u6d4b\u8bd5\u4ee3\u7801\u8bed\u6cd5\uff0c\u8fd9\u4e2a\u53ef\u4ee5\u901a\u8fc7Python\u7684AST\u5e93\u6765\u5b8c\u6210\u3002\u68c0\u67e5\u4ee3\u7801\u7684\u65f6\u5019\uff0c\u6211\u4eec\u4e0d\u4ec5\u9700\u8981\u751f\u6210\u7684\u6d4b\u8bd5\u4ee3\u7801\uff0c\u4e5f\u9700\u8981\u539f\u6765\u7684\u529f\u80fd\u4ee3\u7801\uff0c\u4e0d\u7136\u65e0\u6cd5\u901a\u8fc7\u8bed\u6cd5\u68c0\u67e5\u3002<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\"><span class=\"hljs-keyword\">import<\/span> ast<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">code_start_index = prompt_to_generate_the_unit_test.<span class=\"hljs-title function_\">find<\/span>(<span class=\"hljs-string\">\"```pythonn\"<\/span>) + <span class=\"hljs-title function_\">len<\/span>(<span class=\"hljs-string\">\"```pythonn\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">code_output = prompt_to_generate_the_unit_test[<span class=\"hljs-attr\">code_start_index<\/span>:] + unit_test_response<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\"><span class=\"hljs-attr\">try<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">    ast.<span class=\"hljs-title function_\">parse<\/span>(code_output)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">except <span class=\"hljs-title class_\">SyntaxError<\/span> <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-attr\">e<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">    <span class=\"hljs-title function_\">print<\/span>(f<span class=\"hljs-string\">\"Syntax error in generated code: {e}\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\"><span class=\"hljs-title function_\">print<\/span>(code_output)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\"><\/span>\n<\/code><\/pre>\n<p>\u8f93\u51fa\u7ed3\u679c\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\"><span class=\"hljs-keyword\">import<\/span> pytest  # used <span class=\"hljs-keyword\">for<\/span> our unit tests<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">def <span class=\"hljs-title function_\">format_time<\/span>(days):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">    years, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">365<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">    months, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">30<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">    weeks, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">7<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">    time_str = <span class=\"hljs-string\">\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">    <span class=\"hljs-keyword\">if<\/span> years &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">        time_str += <span class=\"hljs-title function_\">str<\/span>(years) + <span class=\"hljs-string\">\"y\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">    <span class=\"hljs-keyword\">if<\/span> months &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">        time_str += <span class=\"hljs-title function_\">str<\/span>(months) + <span class=\"hljs-string\">\"m\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">    <span class=\"hljs-keyword\">if<\/span> weeks &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\">        time_str += <span class=\"hljs-title function_\">str<\/span>(weeks) + <span class=\"hljs-string\">\"w\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">    <span class=\"hljs-keyword\">if<\/span> days &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">        time_str += <span class=\"hljs-title function_\">str<\/span>(days) + <span class=\"hljs-string\">\"d\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\">    <span class=\"hljs-keyword\">return<\/span> time_str<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">#<span class=\"hljs-title class_\">Below<\/span>, each test <span class=\"hljs-keyword\">case<\/span> is represented by a tuple passed to the @pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-property\">parametrize<\/span> decorator.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">#<span class=\"hljs-title class_\">The<\/span> first element <span class=\"hljs-keyword\">of<\/span> the tuple is the name <span class=\"hljs-keyword\">of<\/span> the test <span class=\"hljs-keyword\">case<\/span>, and the second element is a list <span class=\"hljs-keyword\">of<\/span> <span class=\"hljs-variable language_\">arguments<\/span> to pass to the <span class=\"hljs-keyword\">function<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"22\">#<span class=\"hljs-title class_\">The<\/span> @pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-property\">parametrize<\/span> decorator allows us to write a single test <span class=\"hljs-keyword\">function<\/span> that can be used to test multiple input values.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"23\">@pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-title function_\">parametrize<\/span>(<span class=\"hljs-string\">\"test_input,expected\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"24\">    (<span class=\"hljs-string\">\"Valid Inputs\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"25\">        (<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-string\">\"0d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">0<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"26\">        (<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">\"1d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">1<\/span> day<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"27\">        (<span class=\"hljs-number\">7<\/span>, <span class=\"hljs-string\">\"7d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">7<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"28\">        (<span class=\"hljs-number\">30<\/span>, <span class=\"hljs-string\">\"1m\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">30<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"29\">        (<span class=\"hljs-number\">365<\/span>, <span class=\"hljs-string\">\"1y\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">365<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"30\">        (<span class=\"hljs-number\">400<\/span>, <span class=\"hljs-string\">\"1y35d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">400<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"31\">        (<span class=\"hljs-number\">800<\/span>, <span class=\"hljs-string\">\"2y160d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">800<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"32\">        (<span class=\"hljs-number\">3650<\/span>, <span class=\"hljs-string\">\"10y\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">3650<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"33\">        (<span class=\"hljs-number\">3651<\/span>, <span class=\"hljs-string\">\"10y1d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">3651<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"34\">    ]),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"35\">    (<span class=\"hljs-string\">\"Invalid Inputs\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"36\">        (<span class=\"hljs-string\">\"string\"<\/span>, <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> string input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"37\">        ([], <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> list input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"38\">        ((), <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> tuple input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"39\">        ({}, <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> set input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"40\">        ({<span class=\"hljs-number\">1<\/span>: <span class=\"hljs-number\">1<\/span>}, <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> dictionary input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"41\">        (<span class=\"hljs-number\">1.5<\/span>, <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> float input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"42\">        (<span class=\"hljs-title class_\">None<\/span>, <span class=\"hljs-title class_\">None<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-title class_\">None<\/span> input<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"43\">    ]),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"44\">    (<span class=\"hljs-string\">\"Edge Cases\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"45\">        (<span class=\"hljs-number\">10000000000<\/span>, <span class=\"hljs-string\">\"274247y5m2w6d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> large positive integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"46\">        (<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">\"1d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> small positive integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"47\">        (-<span class=\"hljs-number\">10000000000<\/span>, <span class=\"hljs-string\">\"-274247y5m2w6d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> large negative integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"48\">        (-<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">\"-1d\"<\/span>)  # test <span class=\"hljs-keyword\">for<\/span> small negative integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"49\">    ])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"50\">])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"51\">def <span class=\"hljs-title function_\">test_format_time<\/span>(test_input, expected):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"52\">    # <span class=\"hljs-title class_\">This<\/span> test <span class=\"hljs-keyword\">function<\/span> uses the @pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-property\">parametrize<\/span> decorator to loop through each test <span class=\"hljs-keyword\">case<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"53\">    # <span class=\"hljs-title class_\">The<\/span> test_input parameter contains the name <span class=\"hljs-keyword\">of<\/span> the test <span class=\"hljs-keyword\">case<\/span>, and the expected parameter contains a list <span class=\"hljs-keyword\">of<\/span> <span class=\"hljs-variable language_\">arguments<\/span> to pass to the <span class=\"hljs-keyword\">function<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"54\">    # <span class=\"hljs-title class_\">The<\/span> test_input parameter is not used <span class=\"hljs-keyword\">in<\/span> the test, but is included <span class=\"hljs-keyword\">for<\/span> readability.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"55\">    <span class=\"hljs-keyword\">for<\/span> days, expected_result <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-attr\">expected<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"56\">        # <span class=\"hljs-title class_\">For<\/span> each argument <span class=\"hljs-keyword\">in<\/span> the expected parameter, we call the <span class=\"hljs-title function_\">format_time<\/span>() <span class=\"hljs-keyword\">function<\/span> and compare the result to the expected result.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"57\">        assert <span class=\"hljs-title function_\">format_time<\/span>(days) == expected_result<\/span>\n<\/code><\/pre>\n<p>\u4ece\u4e0a\u9762\u770b\u5230\u6709\u4e9b\u6d4b\u8bd5\u7528\u4f8b\u8ddf\u9884\u671f\u8fd8\u662f\u6709\u5dee\u8ddd\u7684\uff0c\u6bd4\u5982:<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">@pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-title function_\">parametrize<\/span>(<span class=\"hljs-string\">\"test_input,expected\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    (<span class=\"hljs-string\">\"Valid Inputs\"<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">        (<span class=\"hljs-number\">7<\/span>, <span class=\"hljs-string\">\"7d\"<\/span> -&gt; <span class=\"hljs-string\">\"1w\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">7<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">        (<span class=\"hljs-number\">30<\/span>, <span class=\"hljs-string\">\"1m\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">30<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">        (<span class=\"hljs-number\">365<\/span>, <span class=\"hljs-string\">\"1y\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">365<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">        (<span class=\"hljs-number\">400<\/span>, <span class=\"hljs-string\">\"1y35d\"<\/span> -&gt; <span class=\"hljs-string\">\"1y1m5d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">400<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">        (<span class=\"hljs-number\">800<\/span>, <span class=\"hljs-string\">\"2y160d\"<\/span> -&gt; <span class=\"hljs-string\">\"2y5m1w3d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">800<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">        (<span class=\"hljs-number\">3650<\/span>, <span class=\"hljs-string\">\"10y\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">3650<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">        (<span class=\"hljs-number\">3651<\/span>, <span class=\"hljs-string\">\"10y1d\"<\/span>),  # test <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-number\">3651<\/span> days<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">    ]),<\/span>\n<\/code><\/pre>\n<h2 data-id=\"heading-7\">\u4e09\u3001\u7528LangChain\u8fdb\u4e00\u6b65\u5c01\u88c5<\/h2>\n<p>OpenAI \u7684\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u53ea\u662f\u63d0\u4f9b\u4e86\u7b80\u7b80\u5355\u5355\u7684 Completion \u548c Embedding \u8fd9\u6837\u4e24\u4e2a\u6838\u5fc3\u63a5\u53e3\uff0c\u901a\u8fc7\u5408\u7406\u4f7f\u7528\u8fd9\u4e24\u4e2a\u63a5\u53e3\uff0c\u6211\u4eec\u5b8c\u6210\u4e86\u5404\u79cd\u5404\u6837\u590d\u6742\u7684\u4efb\u52a1\u3002<\/p>\n<ul>\n<li>\u901a\u8fc7\u63d0\u793a\u8bed\uff08Prompt\uff09\u91cc\u5305\u542b\u5386\u53f2\u7684\u804a\u5929\u8bb0\u5f55\uff0c\u6211\u4eec\u80fd\u591f\u8ba9 AI \u6839\u636e\u4e0a\u4e0b\u6587\u6b63\u786e\u5730\u56de\u7b54\u95ee\u9898\u3002<\/li>\n<li>\u901a\u8fc7\u5c06 Embedding \u63d0\u524d\u7d22\u5f15\u597d\u5b58\u8d77\u6765\uff0c\u6211\u4eec\u80fd\u591f\u8ba9 AI \u6839\u636e\u5916\u90e8\u77e5\u8bc6\u56de\u7b54\u95ee\u9898\u3002<\/li>\n<li>\u800c\u901a\u8fc7\u591a\u8f6e\u5bf9\u8bdd\uff0c\u5c06 AI \u8fd4\u56de\u7684\u7b54\u6848\u653e\u5728\u65b0\u7684\u95ee\u9898\u91cc\uff0c\u6211\u4eec\u80fd\u591f\u8ba9 AI \u5e2e\u6211\u4eec\u7ed9\u81ea\u5df1\u7684\u4ee3\u7801\u64b0\u5199\u5355\u5143\u6d4b\u8bd5\u3002<\/li>\n<\/ul>\n<p>llama-index \u4e13\u6ce8\u4e8e\u4e3a\u5927\u8bed\u8a00\u6a21\u578b\u7684\u5e94\u7528\u6784\u5efa\u7d22\u5f15\uff0c\u867d\u7136 Langchain \u4e5f\u6709\u7c7b\u4f3c\u7684\u529f\u80fd\uff0c\u4f46\u8fd9\u4e00\u70b9\u5e76\u4e0d\u662f Langchain \u7684\u4e3b\u8981\u5356\u70b9\u3002Langchain \u7684\u7b2c\u4e00\u4e2a\u5356\u70b9\u5176\u5b9e\u5c31\u5728\u5b83\u7684\u540d\u5b57\u91cc\uff0c\u4e5f\u5c31\u662f\u94fe\u5f0f\u8c03\u7528\u3002<\/p>\n<h3 data-id=\"heading-8\">3.1\u3001\u901a\u8fc7 Langchain \u5b9e\u73b0\u81ea\u52a8\u5316\u64b0\u5199\u5355\u5143\u6d4b\u8bd5<\/h3>\n<p>\u4e0a\u9762\u901a\u8fc7\u591a\u6b65\u63d0\u793a\u8bed\u81ea\u52a8\u7ed9\u4ee3\u7801\u5199\u5355\u5143\u6d4b\u8bd5\u3002Langchain\u53ef\u4ee5\u987a\u5e8f\u5730\u901a\u8fc7\u591a\u4e2aPrompt\u8c03\u7528OpenAI\u7684GPT\u6a21\u578b\uff0c\u8fd9\u4e2a\u80fd\u529b\u7528\u6765\u5b9e\u73b0\u81ea\u52a8\u5316\u6d4b\u8bd5\u7684\u529f\u80fd\u6b63\u597d\u5339\u914d\u3002<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">ini<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-ini code-block-extension-codeShowNum\" lang=\"ini\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">from langchain import PromptTemplate, OpenAI, LLMChain<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">from langchain.chains import SequentialChain<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">import ast<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">def write_unit_test(function_to_test, <span class=\"hljs-attr\">unit_test_package<\/span>=<span class=\"hljs-string\">\"pytest\"<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">    <span class=\"hljs-comment\"># \u89e3\u91ca\u6e90\u4ee3\u7801\u7684\u6b65\u9aa4<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">    <span class=\"hljs-attr\">explain_code<\/span> = <span class=\"hljs-string\">\"\"\"\"# How to write great unit tests with {unit_test_package}<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">    In this advanced tutorial for experts, we'll use Python 3.8 and `{unit_test_package}` to write a suite of unit tests to verify the behavior of the following function.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">    ```python<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">    {function_to_test}<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">    ```<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">    Before writing any unit tests, let's review what each element of the function is doing exactly and what the author's intentions may have been.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">    - First,\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\">    <span class=\"hljs-attr\">explain_code_template<\/span> = PromptTemplate(<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\">        <span class=\"hljs-attr\">input_variables<\/span>=[<span class=\"hljs-string\">\"unit_test_package\"<\/span>, <span class=\"hljs-string\">\"function_to_test\"<\/span>],<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">        <span class=\"hljs-attr\">template<\/span>=explain_code<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">    )<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"22\">    <span class=\"hljs-attr\">explain_code_llm<\/span> = OpenAI(model_name=<span class=\"hljs-string\">\"text-davinci-002\"<\/span>, temperature=<span class=\"hljs-number\">0.4<\/span>, max_tokens=<span class=\"hljs-number\">1000<\/span>,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"23\">                              <span class=\"hljs-attr\">top_p<\/span>=<span class=\"hljs-number\">1<\/span>, stop=[<span class=\"hljs-string\">\"nn\"<\/span>, <span class=\"hljs-string\">\"ntn\"<\/span>, <span class=\"hljs-string\">\"n    n\"<\/span>])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"24\">    <span class=\"hljs-attr\">explain_code_step<\/span> = LLMChain(llm=explain_code_llm, prompt=explain_code_template, output_key=<span class=\"hljs-string\">\"code_explaination\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"25\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"26\">    <span class=\"hljs-comment\"># \u521b\u5efa\u6d4b\u8bd5\u8ba1\u5212\u793a\u4f8b\u7684\u6b65\u9aa4<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"27\">    <span class=\"hljs-attr\">test_plan<\/span> = <span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"28\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"29\">    A good unit test suite should aim to:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"30\">    - Test the function's behavior for a wide range of possible inputs<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"31\">    - Test edge cases that the author may not have foreseen<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"32\">    - Take advantage of the features of `{unit_test_package}` to make the tests easy to write and maintain<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"33\">    - Be easy to read and understand, with clean code and descriptive names<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"34\">    - Be deterministic, so that the tests always pass or fail in the same way<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"35\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"36\">    `{unit_test_package}` has many convenient features that make it easy to write and maintain unit tests. We'll use them to write unit tests for the function above.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"37\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"38\">    For this particular function, we'll want our unit tests to handle the following diverse scenarios (and under each scenario, we include a few examples as sub-bullets):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"39\">    -\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"40\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"41\">    <span class=\"hljs-attr\">test_plan_template<\/span> = PromptTemplate(<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"42\">        <span class=\"hljs-attr\">input_variables<\/span>=[<span class=\"hljs-string\">\"unit_test_package\"<\/span>, <span class=\"hljs-string\">\"function_to_test\"<\/span>, <span class=\"hljs-string\">\"code_explaination\"<\/span>],<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"43\">        <span class=\"hljs-attr\">template<\/span>=explain_code+<span class=\"hljs-string\">\"{code_explaination}\"<\/span>+test_plan<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"44\">    )<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"45\">    <span class=\"hljs-attr\">test_plan_llm<\/span> = OpenAI(model_name=<span class=\"hljs-string\">\"text-davinci-002\"<\/span>, temperature=<span class=\"hljs-number\">0.4<\/span>, max_tokens=<span class=\"hljs-number\">1000<\/span>,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"46\">                           <span class=\"hljs-attr\">top_p<\/span>=<span class=\"hljs-number\">1<\/span>, stop=[<span class=\"hljs-string\">\"nn\"<\/span>, <span class=\"hljs-string\">\"ntn\"<\/span>, <span class=\"hljs-string\">\"n    n\"<\/span>])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"47\">    <span class=\"hljs-attr\">test_plan_step<\/span> = LLMChain(llm=test_plan_llm, prompt=test_plan_template, output_key=<span class=\"hljs-string\">\"test_plan\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"48\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"49\">    <span class=\"hljs-comment\"># \u64b0\u5199\u6d4b\u8bd5\u4ee3\u7801\u7684\u6b65\u9aa4<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"50\">    <span class=\"hljs-attr\">starter_comment<\/span> = <span class=\"hljs-string\">\"Below, each test case is represented by a tuple passed to the @pytest.mark.parametrize decorator\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"51\">    <span class=\"hljs-attr\">prompt_to_generate_the_unit_test<\/span> = <span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"52\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"53\">Before going into the individual tests, let's first look at the complete suite of unit tests as a cohesive whole. We've added helpful comments to explain what each line does.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"54\">```python<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"55\">import {unit_test_package}  # used for our unit tests<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"56\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"57\">{function_to_test}<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"58\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"59\">#{starter_comment}\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"60\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"61\">    <span class=\"hljs-attr\">unit_test_template<\/span> = PromptTemplate(<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"62\">        <span class=\"hljs-attr\">input_variables<\/span>=[<span class=\"hljs-string\">\"unit_test_package\"<\/span>, <span class=\"hljs-string\">\"function_to_test\"<\/span>, <span class=\"hljs-string\">\"code_explaination\"<\/span>, <span class=\"hljs-string\">\"test_plan\"<\/span>, <span class=\"hljs-string\">\"starter_comment\"<\/span>],<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"63\">        <span class=\"hljs-attr\">template<\/span>=explain_code+<span class=\"hljs-string\">\"{code_explaination}\"<\/span>+test_plan+<span class=\"hljs-string\">\"{test_plan}\"<\/span>+prompt_to_generate_the_unit_test<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"64\">    )<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"65\">    <span class=\"hljs-attr\">unit_test_llm<\/span> = OpenAI(model_name=<span class=\"hljs-string\">\"text-davinci-002\"<\/span>, temperature=<span class=\"hljs-number\">0.4<\/span>, max_tokens=<span class=\"hljs-number\">1000<\/span>, stop=<span class=\"hljs-string\">\"```\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"66\">    <span class=\"hljs-attr\">unit_test_step<\/span> = LLMChain(llm=unit_test_llm, prompt=unit_test_template, output_key=<span class=\"hljs-string\">\"unit_test\"<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"67\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"68\">    <span class=\"hljs-attr\">sequential_chain<\/span> = SequentialChain(chains=[explain_code_step, test_plan_step, unit_test_step],<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"69\">                                       <span class=\"hljs-attr\">input_variables<\/span>=[<span class=\"hljs-string\">\"unit_test_package\"<\/span>, <span class=\"hljs-string\">\"function_to_test\"<\/span>, <span class=\"hljs-string\">\"starter_comment\"<\/span>],<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"70\">                                       <span class=\"hljs-attr\">verbose<\/span>=<span class=\"hljs-literal\">True<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"71\">    <span class=\"hljs-attr\">answer<\/span> = sequential_chain.run(unit_test_package=unit_test_package, function_to_test=function_to_test,<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"72\">                                  <span class=\"hljs-attr\">starter_comment<\/span>=starter_comment)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"73\">    return f\"\"\"<span class=\"hljs-comment\">#{starter_comment}\"\"\"+answer<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"74\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"75\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"76\"><span class=\"hljs-attr\">code<\/span> = <span class=\"hljs-string\">\"\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"77\">def format_time(days):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"78\">    years, days = divmod(days, 365)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"79\">    months, days = divmod(days, 30)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"80\">    weeks, days = divmod(days, 7)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"81\">    time_str = \"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"82\">    if years &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"83\">        time_str += str(years) + \"y\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"84\">    if months &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"85\">        time_str += str(months) + \"m\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"86\">    if weeks &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"87\">        time_str += str(weeks) + \"w\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"88\">    if days &gt; 0:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"89\">        time_str += str(days) + \"d\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"90\">    return time_str<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"91\">\"\"\"<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"92\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"93\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"94\">def write_unit_test_automatically(code, <span class=\"hljs-attr\">retry<\/span>=<span class=\"hljs-number\">3<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"95\">    <span class=\"hljs-attr\">unit_test_code<\/span> = write_unit_test(code)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"96\">    <span class=\"hljs-attr\">all_code<\/span> = code+unit_test_code<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"97\">    <span class=\"hljs-attr\">tried<\/span> = <span class=\"hljs-number\">0<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"98\">    while tried &lt; retry:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"99\">        try:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"100\">            ast.parse(all_code)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"101\">            return all_code<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"102\">        except SyntaxError as e:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"103\">            print(f\"Syntax error in generated code: {e}\")<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"104\">            <span class=\"hljs-attr\">all_code<\/span> = code+write_unit_test(code)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"105\">            tried += 1<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"106\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"107\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"108\">print(write_unit_test_automatically(code))<\/span>\n<\/code><\/pre>\n<p>\u8f93\u51fa\uff1a<\/p>\n<pre><\/div><div class=\"code-block-extension-headerRight\"><span class=\"code-block-extension-lang\">js<\/span><div class=\"code-block-extension-copyCodeBtn\">\u590d\u5236\u4ee3\u7801<\/div><\/div><\/div><code class=\"hljs language-js code-block-extension-codeShowNum\" lang=\"js\"><span class=\"code-block-extension-codeLine\" data-line-num=\"1\">def <span class=\"hljs-title function_\">format_time<\/span>(days):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"2\">    years, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">365<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"3\">    months, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">30<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"4\">    weeks, days = <span class=\"hljs-title function_\">divmod<\/span>(days, <span class=\"hljs-number\">7<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"5\">    time_str = <span class=\"hljs-string\">\"\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"6\">    <span class=\"hljs-keyword\">if<\/span> years &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"7\">        time_str += <span class=\"hljs-title function_\">str<\/span>(years) + <span class=\"hljs-string\">\"y\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"8\">    <span class=\"hljs-keyword\">if<\/span> months &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"9\">        time_str += <span class=\"hljs-title function_\">str<\/span>(months) + <span class=\"hljs-string\">\"m\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"10\">    <span class=\"hljs-keyword\">if<\/span> weeks &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"11\">        time_str += <span class=\"hljs-title function_\">str<\/span>(weeks) + <span class=\"hljs-string\">\"w\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"12\">    <span class=\"hljs-keyword\">if<\/span> days &gt; <span class=\"hljs-number\">0<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"13\">        time_str += <span class=\"hljs-title function_\">str<\/span>(days) + <span class=\"hljs-string\">\"d\"<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"14\">    <span class=\"hljs-keyword\">return<\/span> time_str<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"15\">#<span class=\"hljs-title class_\">Below<\/span>, each test <span class=\"hljs-keyword\">case<\/span> is represented by a tuple passed to the @pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-property\">parametrize<\/span> decorator.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"16\">#<span class=\"hljs-title class_\">The<\/span> first element <span class=\"hljs-keyword\">of<\/span> the tuple is the name <span class=\"hljs-keyword\">of<\/span> the test <span class=\"hljs-keyword\">case<\/span>, and the second element is a list <span class=\"hljs-keyword\">of<\/span> tuples.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"17\">#<span class=\"hljs-title class_\">Each<\/span> tuple <span class=\"hljs-keyword\">in<\/span> the list <span class=\"hljs-keyword\">of<\/span> tuples represents an individual test.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"18\">#<span class=\"hljs-title class_\">The<\/span> first element <span class=\"hljs-keyword\">of<\/span> each tuple is the input to the <span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">days<\/span>), and the second element is the expected output <span class=\"hljs-keyword\">of<\/span> the <span class=\"hljs-keyword\">function<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"19\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"20\">@pytest.<span class=\"hljs-property\">mark<\/span>.<span class=\"hljs-title function_\">parametrize<\/span>(<span class=\"hljs-string\">'test_case_name, test_cases'<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"21\">    # <span class=\"hljs-title class_\">Test<\/span> cases <span class=\"hljs-keyword\">for<\/span> when the days argument is a positive integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"22\">    (<span class=\"hljs-string\">'positive_int'<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"23\">        (<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">'1d'<\/span>),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"24\">        (<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-string\">'10d'<\/span>),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"25\">        (<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-string\">'1y3m2w1d'<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"26\">    ]),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"27\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"28\">    # <span class=\"hljs-title class_\">Test<\/span> cases <span class=\"hljs-keyword\">for<\/span> when the days argument is <span class=\"hljs-number\">0<\/span><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"29\">    (<span class=\"hljs-string\">'zero'<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"30\">        (<span class=\"hljs-number\">0<\/span>, <span class=\"hljs-string\">''<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"31\">    ]),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"32\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"33\">    # <span class=\"hljs-title class_\">Test<\/span> cases <span class=\"hljs-keyword\">for<\/span> when the days argument is negative<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"34\">    (<span class=\"hljs-string\">'negative_int'<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"35\">        (-<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">'-1d'<\/span>),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"36\">        (-<span class=\"hljs-number\">10<\/span>, <span class=\"hljs-string\">'-10d'<\/span>),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"37\">        (-<span class=\"hljs-number\">100<\/span>, <span class=\"hljs-string\">'-1y-3m-2w-1d'<\/span>)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"38\">    ]),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"39\"><\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"40\">    # <span class=\"hljs-title class_\">Test<\/span> cases <span class=\"hljs-keyword\">for<\/span> when the days argument is not an integer<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"41\">    (<span class=\"hljs-string\">'non_int'<\/span>, [<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"42\">        (<span class=\"hljs-number\">1.5<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">TypeError<\/span>)),<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"43\">        (<span class=\"hljs-string\">'1'<\/span>, pytest.<span class=\"hljs-title function_\">raises<\/span>(<span class=\"hljs-title class_\">TypeError<\/span>))<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"44\">    ])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"45\">])<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"46\">def <span class=\"hljs-title function_\">test_format_time<\/span>(days, expected_output):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"47\">    # <span class=\"hljs-title class_\">This<\/span> test <span class=\"hljs-keyword\">function<\/span> is called once <span class=\"hljs-keyword\">for<\/span> each test <span class=\"hljs-keyword\">case<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"48\">    # days is set to the input <span class=\"hljs-keyword\">for<\/span> the <span class=\"hljs-keyword\">function<\/span>, and expected_output is set to the expected output <span class=\"hljs-keyword\">of<\/span> the <span class=\"hljs-keyword\">function<\/span>.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"49\">    # <span class=\"hljs-title class_\">We<\/span> can use the pytest.<span class=\"hljs-property\">raises<\/span> context manager to test <span class=\"hljs-keyword\">for<\/span> exceptions.<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"50\">    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-title function_\">isinstance<\/span>(expected_output, type) and <span class=\"hljs-title function_\">issubclass<\/span>(expected_output, <span class=\"hljs-title class_\">Exception<\/span>):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"51\">        <span class=\"hljs-keyword\">with<\/span> pytest.<span class=\"hljs-title function_\">raises<\/span>(expected_output):<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"52\">            <span class=\"hljs-title function_\">format_time<\/span>(days)<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"53\">    <span class=\"hljs-attr\">else<\/span>:<\/span>\n<span class=\"code-block-extension-codeLine\" data-line-num=\"54\">        assert <span class=\"hljs-title function_\">format_time<\/span>(days) == expected_output<\/span>\n<\/code><\/pre>\n<h2 data-id=\"heading-9\">\u56db\u3001\u603b\u7ed3<\/h2>\n<p>\u60f3\u8981\u901a\u8fc7\u5927\u8bed\u8a00\u6a21\u578b\uff0c\u5b8c\u6210\u4e00\u4e2a\u590d\u6742\u7684\u4efb\u52a1\uff0c\u5f80\u5f80\u9700\u8981\u6211\u4eec\u591a\u6b21\u5411 AI \u63d0\u95ee\uff0c\u5e76\u4e14\u524d\u9762\u63d0\u95ee\u7684\u7b54\u6848\uff0c\u53ef\u80fd\u662f\u540e\u9762\u95ee\u9898\u8f93\u5165\u7684\u4e00\u90e8\u5206\u3002LangChain \u901a\u8fc7\u5c06\u591a\u4e2a LLMChain \u7ec4\u5408\u6210\u4e00\u4e2a SequantialChain \u5e76\u987a\u5e8f\u6267\u884c\uff0c\u5927\u5927\u7b80\u5316\u4e86\u8fd9\u7c7b\u4efb\u52a1\u7684\u5f00\u53d1\u5de5\u4f5c\u3002<\/p>\n<p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.nicekj.com\/wp-content\/uploads\/replace\/8400bbfc35cbf8c900cc078b58448e54.png\" alt=\"image.png\" \/><\/figure>\n<\/p>","protected":false},"excerpt":{"rendered":"<p>\u4e00\u3001\u7528ChatGPT\u76f4\u63a5\u751f\u6210\u7684\u6d4b\u8bd5\u7528\u4f8b \u8981\u5199\u6d4b\u8bd5\uff0c\u6211\u4eec\u8981\u5148\u6709\u4e00\u4e2a\u7a0b\u5e8f\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u4e2a\u9898\u76ee\u672c\u8eab\u5c31\u5728AI\u7684\u8bad\u7ec3\u6570\u636e\u96c6\u91cc\u9762\uff0c\u5b83\u76f4\u63a5\u77e5\u9053\u7b54\u6848\u3002 \u6211\u4eec\u7528\u4e00\u4e2a\u6709\u610f\u601d\u7684\u5c0f\u9898\u76ee\uff0c\u4e5f\u5c31\u662f\u8ba9Python\u6839\u636e\u6211\u4eec\u8f93\u5165\u7684\u4e00\u4e2a\u6574<\/p>\n","protected":false},"author":1,"featured_media":2311,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"rank_math_title":"AI\u8d4b\u80fd\uff1a\u81ea\u52a8\u751f\u6210\u5355\u5143\u6d4b\u8bd5\u7528\u4f8b\u65b0\u65b9\u6cd5 - \u5948\u65af\u79d1\u6280\u793e\u533a","rank_math_description":"\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u5982\u4f55\u5229\u7528ChatGPT\u3001OpenAI\u548cLangChain\u7b49AI\u5de5\u5177\u81ea\u52a8\u751f\u6210\u5355\u5143\u6d4b\u8bd5\u7528\u4f8b\uff0c\u63d0\u9ad8\u4ee3\u7801\u6d4b\u8bd5\u6548\u7387\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u4f7f\u7528\u6b65\u9aa4\uff0c\u5e76\u63d0\u4f9b\u4e86\u4ee3\u7801\u793a\u4f8b\u3002","rank_math_focus_keyword":"ChatGPT, \u5355\u5143\u6d4b\u8bd5, OpenAI, LangChain, \u4ee3\u7801\u751f\u6210","views":"31","footnotes":""},"categories":[3],"tags":[136,126,127,128,129],"collection":[],"class_list":["post-1191","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-fenlei2","tag-136","tag-gpt","tag-ai","tag-128","tag-129"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/posts\/1191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/comments?post=1191"}],"version-history":[{"count":0,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/posts\/1191\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/media\/2311"}],"wp:attachment":[{"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/media?parent=1191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/categories?post=1191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/tags?post=1191"},{"taxonomy":"collection","embeddable":true,"href":"https:\/\/www.nicekj.com\/nicekj2024\/wp\/v2\/collection?post=1191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}