banner
Feb 14, 2023
445 Views

Áp dụng ChatGPT viết Unit test, thêm comment, convert code, tối ưu…

Written by
banner

Coding, review code, unit test là công việc có phần nhàm chán khi:

  • Dựng khung.
  • Viết các test case chắc chắn cần pass

Nhưng lại vui vẻ khi:

  • Được viết các corner case

Thế tại sao không để ChatGPT làm việc nhàm chán và mình làm những thứ vui vẻ nhỉ.

Hỏi: function lấy bừa trên mạng, chưa tính tới nhiều trường hợp, bạn cho tôi test case bằng Jest nào

function intToEnglish(number) {

  var NS = [
    { value: 1000000000, str: "Billion" },
    { value: 1000000, str: "Million" },
    { value: 1000, str: "Thousand" },
    { value: 100, str: "Hundred" },
    { value: 90, str: "Ninety" },
    { value: 80, str: "Eighty" },
    { value: 70, str: "Seventy" },
    { value: 60, str: "Sixty" },
    { value: 50, str: "Fifty" },
    { value: 40, str: "Forty" },
    { value: 30, str: "Thirty" },
    { value: 20, str: "Twenty" },
    { value: 19, str: "Nineteen" },
    { value: 18, str: "Eighteen" },
    { value: 17, str: "Seventeen" },
    { value: 16, str: "Sixteen" },
    { value: 15, str: "Fifteen" },
    { value: 14, str: "Fourteen" },
    { value: 13, str: "Thirteen" },
    { value: 12, str: "Twelve" },
    { value: 11, str: "Eleven" },
    { value: 10, str: "Ten" },
    { value: 9, str: "Nine" },
    { value: 8, str: "Eight" },
    { value: 7, str: "Seven" },
    { value: 6, str: "Six" },
    { value: 5, str: "Five" },
    { value: 4, str: "Four" },
    { value: 3, str: "Three" },
    { value: 2, str: "Two" },
    { value: 1, str: "One" }
  ];

  var result = '';
  for (var n of NS) {
    if (number >= n.value) {
      if (number <= 99) {
        result += n.str;
        number -= n.value;
        if (number > 0) result += ' ';
      } else {
        var t = Math.floor(number / n.value);
        // console.log(t);
        var d = number % n.value;
        if (d > 0) {
          return intToEnglish(t) + ' ' + n.str + ' ' + intToEnglish(d);
        } else {
          return intToEnglish(t) + ' ' + n.str;
        }

      }
    }
  }
  return result;
}

Đáp: đây là bộ test nếu sếp muốn dùng Jest nhé

describe("intToEnglish", () => {
  test("converts 1 to One", () => {
    expect(intToEnglish(1)).toBe("One");
  });
  test("converts 11 to Eleven", () => {
    expect(intToEnglish(11)).toBe("Eleven");
  });
  test("converts 16 to Sixteen", () => {
    expect(intToEnglish(16)).toBe("Sixteen");
  });
  test("converts 19 to Nineteen", () => {
    expect(intToEnglish(19)).toBe("Nineteen");
  });
  test("converts 23 to Twenty Three", () => {
    expect(intToEnglish(23)).toBe("Twenty Three");
  });
  test("converts 102 to One Hundred Two", () => {
    expect(intToEnglish(102)).toBe("One Hundred Two");
  });
  test("converts 100 to One Hundred", () => {
    expect(intToEnglish(100)).toBe("One Hundred");
  });
  test("converts 1000 to One Thousand", () => {
    expect(intToEnglish(1000)).toBe("One Thousand");
  });
  test("converts 10000 to Ten Thousand", () => {
    expect(intToEnglish(10000)).toBe("Ten Thousand");
  });
  test("converts 100000 to One Hundred Thousand", () => {
    expect(intToEnglish(100000)).toBe("One Hundred Thousand");
  });
  test("converts 1000000 to One Million", () => {
    expect(intToEnglish(1000000)).toBe("One Million");
  });
  test("converts 10000000 to Ten Million", () => {
    expect(intToEnglish(10000000)).toBe("Ten Million");
  });
  test("converts 100000000 to One Hundred Million", () => {
    expect(intToEnglish(100000000)).toBe("One Hundred Million");
  });
  test("converts 1000000000 to One Billion", () => {
    expect(intToEnglish(1000000000)).toBe("One Billion");
  });
});

Hỏi: thôi viết lại bằng Mocha + Chai đi, team đang dùng cái đó có vẻ ưng mắt hơn

Đáp: muốn Chai thì Chai

const expect = require("chai").expect;

describe("intToEnglish", () => {
  it("converts 1 to One", () => {
    expect(intToEnglish(1)).to.equal("One");
  });
  it("converts 11 to Eleven", () => {
    expect(intToEnglish(11)).to.equal("Eleven");
  });
  it("converts 16 to Sixteen", () => {
    expect(intToEnglish(16)).to.equal("Sixteen");
  });
  it("converts 19 to Nineteen", () => {
    expect(intToEnglish(19)).to.equal("Nineteen");
  });
  it("converts 23 to Twenty Three", () => {
    expect(intToEnglish(23)).to.equal("Twenty Three");
  });
  it("converts 102 to One Hundred Two", () => {
    expect(intToEnglish(102)).to.equal("One Hundred Two");
  });
  it("converts 100 to One Hundred", () => {
    expect(intToEnglish(100)).to.equal("One Hundred");
  });
  it("converts 1000 to One Thousand", () => {
    expect(intToEnglish(1000)).to.equal("One Thousand");
  });
  it("converts 10000 to Ten Thousand", () => {
    expect(intToEnglish(10000)).to.equal("Ten Thousand");
  });
  it("converts 100000 to One Hundred Thousand", () => {
    expect(intToEnglish(100000)).to.equal("One Hundred Thousand");
  });
  it("converts 1000000 to One Million", () => {
    expect(intToEnglish(1000000)).to.equal("One Million");
  });
  it("converts 10000000 to Ten Million", () => {
    expect(intToEnglish(10000000)).to.equal("Ten Million");
  });
  it("converts 100000000 to One Hundred Million", () => {
    expect(intToEnglish(100000000)).to.equal("One Hundred Million");
  });
  it("converts 1000000000 to One Billion", () => {
    expect(intToEnglish(1000000000)).to.equal("One Billion");
  });
});

Hỏi: sẵn tiện convert sang python hộ tôi, tôi chuyên python hơn.

function intToEnglish(number) {

  var NS = [
    { value: 1000000000, str: "Billion" },
    { value: 1000000, str: "Million" },
    { value: 1000, str: "Thousand" },
    { value: 100, str: "Hundred" },
    { value: 90, str: "Ninety" },
    { value: 80, str: "Eighty" },
    { value: 70, str: "Seventy" },
    { value: 60, str: "Sixty" },
    { value: 50, str: "Fifty" },
    { value: 40, str: "Forty" },
    { value: 30, str: "Thirty" },
    { value: 20, str: "Twenty" },
    { value: 19, str: "Nineteen" },
    { value: 18, str: "Eighteen" },
    { value: 17, str: "Seventeen" },
    { value: 16, str: "Sixteen" },
    { value: 15, str: "Fifteen" },
    { value: 14, str: "Fourteen" },
    { value: 13, str: "Thirteen" },
    { value: 12, str: "Twelve" },
    { value: 11, str: "Eleven" },
    { value: 10, str: "Ten" },
    { value: 9, str: "Nine" },
    { value: 8, str: "Eight" },
    { value: 7, str: "Seven" },
    { value: 6, str: "Six" },
    { value: 5, str: "Five" },
    { value: 4, str: "Four" },
    { value: 3, str: "Three" },
    { value: 2, str: "Two" },
    { value: 1, str: "One" }
  ];

  var result = '';
  for (var n of NS) {
    if (number >= n.value) {
      if (number <= 99) {
        result += n.str;
        number -= n.value;
        if (number > 0) result += ' ';
      } else {
        var t = Math.floor(number / n.value);
        // console.log(t);
        var d = number % n.value;
        if (d > 0) {
          return intToEnglish(t) + ' ' + n.str + ' ' + intToEnglish(d);
        } else {
          return intToEnglish(t) + ' ' + n.str;
        }

      }
    }
  }
  return result;
}

Đáp: thích python có python

def intToEnglish(number):
    NS = [
        {'value': 1000000000, 'str': "Billion"},
        {'value': 1000000, 'str': "Million"},
        {'value': 1000, 'str': "Thousand"},
        {'value': 100, 'str': "Hundred"},
        {'value': 90, 'str': "Ninety"},
        {'value': 80, 'str': "Eighty"},
        {'value': 70, 'str': "Seventy"},
        {'value': 60, 'str': "Sixty"},
        {'value': 50, 'str': "Fifty"},
        {'value': 40, 'str': "Forty"},
        {'value': 30, 'str': "Thirty"},
        {'value': 20, 'str': "Twenty"},
        {'value': 19, 'str': "Nineteen"},
        {'value': 18, 'str': "Eighteen"},
        {'value': 17, 'str': "Seventeen"},
        {'value': 16, 'str': "Sixteen"},
        {'value': 15, 'str': "Fifteen"},
        {'value': 14, 'str': "Fourteen"},
        {'value': 13, 'str': "Thirteen"},
        {'value': 12, 'str': "Twelve"},
        {'value': 11, 'str': "Eleven"},
        {'value': 10, 'str': "Ten"},
        {'value': 9, 'str': "Nine"},
        {'value': 8, 'str': "Eight"},
        {'value': 7, 'str': "Seven"},
        {'value': 6, 'str': "Six"},
        {'value': 5, 'str': "Five"},
        {'value': 4, 'str': "Four"},
        {'value': 3, 'str': "Three"},
        {'value': 2, 'str': "Two"},
        {'value': 1, 'str': "One"}
    ]

    result = ''
    for n in NS:
        if number >= n['value']:
            if number <= 99:
                result += n['str']
                number -= n['value']
                if number > 0:
                    result += ' '
            else:
                t = number // n['value']
                d = number % n['value']
                if d > 0:
                    return intToEnglish(t) + ' ' + n['str'] + ' ' + intToEnglish(d)
                else:
                    return intToEnglish(t) + ' ' + n['str']

    return result

Hỏi: viết hộ luôn cái unit test xem nào

Đáp: đây, unit test mẫu đây

import unittest
from convert_nodejs_to_python import intToEnglish

class TestIntToEnglish(unittest.TestCase):
    def test_intToEnglish(self):
        # Test cases for numbers less than 20
        self.assertEqual(intToEnglish(1), 'One')
        self.assertEqual(intToEnglish(2), 'Two')
        self.assertEqual(intToEnglish(11), 'Eleven')
        self.assertEqual(intToEnglish(19), 'Nineteen')
        
        # Test cases for numbers greater than 20 and less than 100
        self.assertEqual(intToEnglish(20), 'Twenty')
        self.assertEqual(intToEnglish(22), 'Twenty Two')
        self.assertEqual(intToEnglish(50), 'Fifty')
        self.assertEqual(intToEnglish(99), 'Ninety Nine')
        
        # Test cases for numbers greater than 100 and less than 1000
        self.assertEqual(intToEnglish(100), 'One Hundred')
        self.assertEqual(intToEnglish(150), 'One Hundred Fifty')
        self.assertEqual(intToEnglish(999), 'Nine Hundred Ninety Nine')
        
        # Test cases for numbers greater than 1000 and less than 1000000000
        self.assertEqual(intToEnglish(1000), 'One Thousand')
        self.assertEqual(intToEnglish(1000000), 'One Million')
        self.assertEqual(intToEnglish(1000000000), 'One Billion')

if __name__ == '__main__':
    unittest.main()

Hỏi: Đoạn này nghĩ nó đang thiếu các trường hợp biên như âm hoặc số lớn hơn 1 tỉ nên mới bảo "mày tính tới việc bao phủ nhiều điều kiện hơn đi"

Đáp: nó đoán trúng phóc cái mình cần

import unittest
from convert_nodejs_to_python import intToEnglish

class TestIntToEnglish(unittest.TestCase):
    def test_intToEnglish(self):
        # Test cases for numbers less than 20
        self.assertEqual(intToEnglish(1), 'One')
        self.assertEqual(intToEnglish(2), 'Two')
        self.assertEqual(intToEnglish(11), 'Eleven')
        self.assertEqual(intToEnglish(19), 'Nineteen')
        
        # Test cases for numbers greater than 20 and less than 100
        self.assertEqual(intToEnglish(20), 'Twenty')
        self.assertEqual(intToEnglish(22), 'Twenty Two')
        self.assertEqual(intToEnglish(50), 'Fifty')
        self.assertEqual(intToEnglish(99), 'Ninety Nine')
        
        # Test cases for numbers greater than 100 and less than 1000
        self.assertEqual(intToEnglish(100), 'One Hundred')
        self.assertEqual(intToEnglish(150), 'One Hundred Fifty')
        self.assertEqual(intToEnglish(999), 'Nine Hundred Ninety Nine')
        
        # Test cases for numbers greater than 1000 and less than 1000000000
        self.assertEqual(intToEnglish(1000), 'One Thousand')
        self.assertEqual(intToEnglish(1000000), 'One Million')
        self.assertEqual(intToEnglish(1000000000), 'One Billion')
        
        # Test case for number zero
        self.assertEqual(intToEnglish(0), '')
        
        # Test case for a large number
        self.assertEqual(intToEnglish(1000000000), 'One Billion')
        self.assertEqual(intToEnglish(1000000001), 'One Billion One')
        self.assertEqual(intToEnglish(1001001001), 'One Billion One Thousand One Hundred One')
        
        # Test case for negative numbers
        self.assertEqual(intToEnglish(-1), '')

if __name__ == '__main__':
    unittest.main()

#These additional tests increase the coverage of the conditions in the code, and test the function's behavior in different scenarios, such as handling large numbers, zero, and negative numbers.

Hỏi: Giờ thì thêm hộ tao comment cho code đi

Đáp: ok bẹn êi

def int_to_english(number):
    """
    Converts an integer to its equivalent English representation.
    Example: 123 -> "One Hundred Twenty Three"
    """
    NS = [
        {'value': 1000000000, 'str': 'Billion'},
        {'value': 1000000, 'str': 'Million'},
        {'value': 1000, 'str': 'Thousand'},
        {'value': 100, 'str': 'Hundred'},
        {'value': 90, 'str': 'Ninety'},
        {'value': 80, 'str': 'Eighty'},
        {'value': 70, 'str': 'Seventy'},
        {'value': 60, 'str': 'Sixty'},
        {'value': 50, 'str': 'Fifty'},
        {'value': 40, 'str': 'Forty'},
        {'value': 30, 'str': 'Thirty'},
        {'value': 20, 'str': 'Twenty'},
        {'value': 19, 'str': 'Nineteen'},
        {'value': 18, 'str': 'Eighteen'},
        {'value': 17, 'str': 'Seventeen'},
        {'value': 16, 'str': 'Sixteen'},
        {'value': 15, 'str': 'Fifteen'},
        {'value': 14, 'str': 'Fourteen'},
        {'value': 13, 'str': 'Thirteen'},
        {'value': 12, 'str': 'Twelve'},
        {'value': 11, 'str': 'Eleven'},
        {'value': 10, 'str': 'Ten'},
        {'value': 9, 'str': 'Nine'},
        {'value': 8, 'str': 'Eight'},
        {'value': 7, 'str': 'Seven'},
        {'value': 6, 'str': 'Six'},
        {'value': 5, 'str': 'Five'},
        {'value': 4, 'str': 'Four'},
        {'value': 3, 'str': 'Three'},
        {'value': 2, 'str': 'Two'},
        {'value': 1, 'str': 'One'}
    ]

    result = ''
    for n in NS:
        if number >= n['value']:
            # Check if the number is less than or equal to 99
            if number <= 99:
                result += n['str']
                number -= n['value']
                # If the number is not 0, add a space after the str value
                if number > 0:
                    result += ' '
            else:
                # Calculate the number of times the value fits into the given number
                t = number // n['value']
                # Calculate the remaining number after dividing with the value
                d = number % n['value']
                if d > 0:
                    return int_to_english(t) + ' ' + n['str'] + ' ' + int_to_english(d)
                else:
                    return int_to_english(t) + ' ' + n['str']

    return result

Hỏi: tao có hàm python này lười comment quá, làm hộ cái

def delete_product(self, request):
        """Delete product from Elasticsearch db
        Args: request forms contain product id and delete time
        Returns:
            - success mess if adding product successfully
            - error mess if process errors happen when delete product's inventory
        """
        try:
            if request.form.get(self.DATA_PARAMETER_NAME) is None:
                self.logger.error(f"Missing {self.DATA_PARAMETER_NAME} parameter")
                return create_http_response_body(status=400, error=f"missing '{self.DATA_PARAMETER_NAME}' parameter")
            mess_body = json.loads(request.form.get(self.DATA_PARAMETER_NAME))
            self.logger.info(f'DELETE product request - Received message: {mess_body}')
            try:
                self.es_client.delete(index=self.INDEX_PRODUCT, id=mess_body["id"])
            except ElasticsearchException as es_exp:
                self.logger.error(f'DELETE product request - ES clusters delete failed: \n{es_exp}')
                return create_http_response_body(status=404, error=str(es_exp))
            return create_http_response_body(status=200)  # Return mess if delete product successfully
        except Exception as py_exp:
            self.logger.exception(f'DELETE product request - Failed: \n{str(py_exp)}')
            return create_http_response_body(status=400, error=str(py_exp))

Đáp: chơi luôn

def delete_product(self, request):
    """
    Delete a product from the Elasticsearch database.
    Args:
        request: A request object containing the product ID and delete time in its form.
    Returns:
        A response object indicating the success or failure of the operation.
    """
    try:
        # Check if the required data parameter is present in the request object
        if request.form.get(self.DATA_PARAMETER_NAME) is None:
            self.logger.error(f"Missing {self.DATA_PARAMETER_NAME} parameter")
            # Return an HTTP response with a 400 status code and an error message indicating the missing parameter
            return create_http_response_body(status=400, error=f"missing '{self.DATA_PARAMETER_NAME}' parameter")
        
        # Parse the message body and log a message with the received data
        mess_body = json.loads(request.form.get(self.DATA_PARAMETER_NAME))
        self.logger.info(f'DELETE product request - Received message: {mess_body}')
        
        # Attempt to delete the product from the Elasticsearch index
        try:
            self.es_client.delete(index=self.INDEX_PRODUCT, id=mess_body["id"])
        except ElasticsearchException as es_exp:
            self.logger.error(f'DELETE product request - ES clusters delete failed: \n{es_exp}')
            # Return an HTTP response with a 404 status code and the error message
            return create_http_response_body(status=404, error=str(es_exp))
        
        # Return an HTTP response with a 200 status code indicating the success
        return create_http_response_body(status=200)
    
    except Exception as py_exp:
        # Log the exception and return an HTTP response with a 400 status code and the error message
        self.logger.exception(f'DELETE product request - Failed: \n{str(py_exp)}')
        return create_http_response_body(status=400, error=str(py_exp))

Hỏi: tối ưu và giải thích xem nào

Cound you optimize it and explain why ?

Đáp: đây

def delete_product(self, request):
    """
    Delete a product from the Elasticsearch database.
    Args:
        request: A request object containing the product ID and delete time in its form.
    Returns:
        A response object indicating the success or failure of the operation.
    """
    # Check if the required data parameter is present in the request object
    if self.DATA_PARAMETER_NAME not in request.form:
        error_message = f"Missing {self.DATA_PARAMETER_NAME} parameter"
        self.logger.error(error_message)
        # Return an HTTP response with a 400 status code and an error message indicating the missing parameter
        return create_http_response_body(status=400, error=error_message)

    try:
        # Parse the message body and log a message with the received data
        mess_body = json.loads(request.form[self.DATA_PARAMETER_NAME])
        self.logger.info(f'DELETE product request - Received message: {mess_body}')
        
        # Attempt to delete the product from the Elasticsearch index
        self.es_client.delete(index=self.INDEX_PRODUCT, id=mess_body["id"])
        
        # Return an HTTP response with a 200 status code indicating the success
        return create_http_response_body(status=200)
    
    except ElasticsearchException as es_exp:
        # Log the error and return an HTTP response with a 404 status code and the error message
        self.logger.error(f'DELETE product request - ES clusters delete failed: \n{es_exp}')
        return create_http_response_body(status=404, error=str(es_exp))
    
    except Exception as py_exp:
        # Log the exception and return an HTTP response with a 400 status code and the error message
        self.logger.exception(f'DELETE product request - Failed: \n{str(py_exp)}')
        return create_http_response_body(status=400, error=str(py_exp))

"""
Here's how the code has been optimized:

Instead of checking if the data parameter is None using the get() method, we can use the in operator to check if the parameter is in the form. This is more efficient as it only accesses the form dictionary once.
The error message can be stored in a variable for clarity and to avoid repetition.
We can remove the nested try-except block and catch the ElasticsearchException directly in the main try-except block. This reduces the nesting and makes the code easier to read.
We don't need to convert the ElasticsearchException to a string when creating the error message, as the create_http_response_body() method already handles this.
"""

Note: không phải chatgpt nói gì cũng đúng đâu nhé, luôn phải kiểm tra ;)

Trên đây là 1 ví dụ về việc chatgpt giúp tôi tự động hóa các công việc nhàm chán. Còn bạn ?

Article Tags:
· · · ·
Article Categories:
dev
banner

Leave a Reply

Your email address will not be published. Required fields are marked *