Skip to content

Commit

Permalink
Merge pull request #10 from jcrodriguez1989/develop
Browse files Browse the repository at this point in the history
Release v0.2.0
  • Loading branch information
jcrodriguez1989 authored Mar 3, 2023
2 parents 7dda9c5 + f252b28 commit 81ac647
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 61 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: chatgpt
Type: Package
Title: Interface to 'ChatGPT' from R
Version: 0.1.5
Version: 0.2.0
Authors@R: c(
person(
given = "Juan Cruz", family = "Rodriguez", role = c("aut", "cre"),
Expand All @@ -16,7 +16,7 @@ URL: https://github.com/jcrodriguez1989/chatgpt
BugReports: https://github.com/jcrodriguez1989/chatgpt/issues
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.2.0
RoxygenNote: 7.2.3
Imports:
httr,
jsonlite,
Expand Down
5 changes: 1 addition & 4 deletions R/addins.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ run_addin_ask_chatgpt <- function() {
))
server <- function(input, output, session) {
observeEvent(input$ask_button, {
chatgpt_reply <- trimws(sapply(
getFromNamespace("gpt_get_completions", "chatgpt")(input$question)$choices,
function(x) x$text
))
chatgpt_reply <- ask_chatgpt(input$question)
if (as.logical(Sys.getenv("OPENAI_VERBOSE", TRUE))) {
cat(paste0("\n*** ChatGPT output:\n\n", chatgpt_reply, "\n"))
}
Expand Down
2 changes: 1 addition & 1 deletion R/ask_chatgpt.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
#' @export
#'
ask_chatgpt <- function(question) {
trimws(sapply(gpt_get_completions(question)$choices, function(x) x$text))
parse_response(gpt_get_completions(question))
}
2 changes: 1 addition & 1 deletion R/comment_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
comment_code <- function(code) {
prompt <- paste0('Add inline comments to the following R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
2 changes: 1 addition & 1 deletion R/create_unit_tests.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ create_unit_tests <- function(code) {
prompt <- paste0(
'Create a full testthat file, with test cases for the following R code: "', code, '"'
)
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
2 changes: 1 addition & 1 deletion R/create_variable_name.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
create_variable_name <- function(code) {
prompt <- paste0('Give a good variable name to the result of the following R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
2 changes: 1 addition & 1 deletion R/document_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
document_code <- function(code) {
prompt <- paste0('Document, in roxygen2 format, this R function: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
2 changes: 1 addition & 1 deletion R/explain_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
explain_code <- function(code) {
prompt <- paste0('Explain the following R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
2 changes: 1 addition & 1 deletion R/find_issues_in_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
find_issues_in_code <- function(code) {
prompt <- paste0('Find issues or bugs in the following R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
36 changes: 27 additions & 9 deletions R/gpt_get_completions.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,40 @@ gpt_get_completions <- function(prompt, openai_api_key = Sys.getenv("OPENAI_API_
if (nchar(openai_api_key) == 0) {
stop("`OPENAI_API_KEY` not provided.")
}
# See https://beta.openai.com/docs/api-reference/completions/create
# See https://platform.openai.com/docs/api-reference/chat
# and https://beta.openai.com/docs/api-reference/completions/create
model <- Sys.getenv("OPENAI_MODEL", "gpt-3.5-turbo")
params <- list(
model = Sys.getenv("OPENAI_MODEL", "text-davinci-003"),
model = model,
max_tokens = as.numeric(Sys.getenv("OPENAI_MAX_TOKENS", 256)),
temperature = as.numeric(Sys.getenv("OPENAI_TEMPERATURE", 0.7)),
temperature = as.numeric(Sys.getenv("OPENAI_TEMPERATURE", 1)),
top_p = as.numeric(Sys.getenv("OPENAI_TOP_P", 1)),
frequency_penalty = as.numeric(Sys.getenv("OPENAI_FREQUENCY_PENALTY", 0)),
presence_penalty = as.numeric(Sys.getenv("OPENAI_PRESENCE_PENALTY", 0))
)
if (as.logical(Sys.getenv("OPENAI_VERBOSE", TRUE))) {
cat(paste0("\n*** ChatGPT input:\n\n", prompt, "\n"))
}
content(POST(
"https://api.openai.com/v1/completions",
add_headers("Authorization" = paste("Bearer", openai_api_key)),
content_type_json(),
body = toJSON(c(params, list(prompt = prompt)), auto_unbox = TRUE)
))
if (grepl("gpt-3.5-turbo", model)) {
messages <- list(
list(
role = "system",
content = "You are a helpful assistant with extensive knowledge of R programming."
),
list(role = "user", content = prompt)
)
content(POST(
"https://api.openai.com/v1/chat/completions",
add_headers("Authorization" = paste("Bearer", openai_api_key)),
content_type_json(),
body = toJSON(c(params, list(messages = messages)), auto_unbox = TRUE)
))
} else {
content(POST(
"https://api.openai.com/v1/completions",
add_headers("Authorization" = paste("Bearer", openai_api_key)),
content_type_json(),
body = toJSON(c(params, list(prompt = prompt)), auto_unbox = TRUE)
))
}
}
2 changes: 1 addition & 1 deletion R/optimize_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
optimize_code <- function(code) {
prompt <- paste0('Optimize the following R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
17 changes: 17 additions & 0 deletions R/parse_response.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#' Parse OpenAI API Response
#'
#' Takes the raw response from the OpenAI API and extracts the text content from it.
#' This function is currently designed to differentiate between gpt-3.5-turbo and others.
#'
#' @param raw_response The raw response object returned by the OpenAI API.
#'
#' @return Returns a character vector containing the text content of the response.
#'
parse_response <- function(raw_response) {
# If the model is from the `gpt-3.5-turbo` family, it parses in a different way.
if (grepl("gpt-3.5-turbo", Sys.getenv("OPENAI_MODEL", "gpt-3.5-turbo"))) {
trimws(sapply(raw_response$choices, function(x) x$message$content))
} else {
trimws(sapply(raw_response$choices, function(x) x$text))
}
}
2 changes: 1 addition & 1 deletion R/refactor_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#'
refactor_code <- function(code) {
prompt <- paste0('Refactor the following R code, returning valid R code: "', code, '"')
trimws(sapply(gpt_get_completions(prompt)$choices, function(x) x$text))
parse_response(gpt_get_completions(prompt))
}
6 changes: 3 additions & 3 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ knitr::opts_chunk$set(
# ChatGPT coding assistant for RStudio

<center>
<img width="300" height="400" src="https://media.licdn.com/dms/image/C5622AQG8D9NQ_ePuzA/feedshare-shrink_800/0/1673359083125?e=1676505600&v=beta&t=cnmYmdjyiAZ4gwZqqwJy1UXBJ5IlHWAiLWLQuSEjeYk">
<img width="300" height="400" src="man/figures/chatgpt_meme.jpeg">
<p>Meme by Programming Jokes I IT Humor & Memes</p>
</center>

Expand Down Expand Up @@ -105,9 +105,9 @@ ChatGPT model parameters can be tweaked by using environment variables.

The following environment variables variables can be set to tweak the behavior, as documented in https://beta.openai.com/docs/api-reference/completions/create .

* `OPENAI_MODEL`; defaults to `"text-davinci-003"`
* `OPENAI_MODEL`; defaults to `"gpt-3.5-turbo"`
* `OPENAI_MAX_TOKENS`; defaults to `256`
* `OPENAI_TEMPERATURE`; defaults to `0.7`
* `OPENAI_TEMPERATURE`; defaults to `1`
* `OPENAI_TOP_P`; defaults to `1`
* `OPENAI_FREQUENCY_PENALTY`; defaults to `0`
* `OPENAI_PRESENCE_PENALTY`; defaults to `0`
82 changes: 48 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ChatGPT coding assistant for RStudio

<center>
<img width="300" height="400" src="https://media.licdn.com/dms/image/C5622AQG8D9NQ_ePuzA/feedshare-shrink_800/0/1673359083125?e=1676505600&v=beta&t=cnmYmdjyiAZ4gwZqqwJy1UXBJ5IlHWAiLWLQuSEjeYk">
<img width="300" height="400" src="man/figures/chatgpt_meme.jpeg">
<p>
Meme by Programming Jokes I IT Humor & Memes
</p>
Expand Down Expand Up @@ -52,6 +52,8 @@ coding. Current existing addins:

- **Ask ChatGPT:** Opens an interactive chat session with ChatGPT
- **Comment selected code:** Comment the selected code
- **Create unit tests:** Create testthat unit tests for the selected
code
- **Create variable name:** Create a name for a variable that would be
assigned the result of this code
- **Document code (in roxygen2 format):** Document a function
Expand All @@ -65,6 +67,17 @@ coding. Current existing addins:

## Code Examples

#### `ask_chatgpt`

``` r
> cat(ask_chatgpt("What do you think about R language?"))

*** ChatGPT input:

What do you think about R language?
R language is a powerful, open-source programming language for statistical computing and graphical visualization. Its an excellent choice for data analysis and statistical modeling. R has a wide range of features available and is highly extensible, allowing users to create custom packages and add-ons. With many different tutorials and guides available to help get started, R is an accessible language and can be used for both simple and complex statistical analysis and data analysis projects.
```

#### `comment_code`

``` r
Expand All @@ -75,9 +88,9 @@ coding. Current existing addins:
Add inline comments to the following R code: "for (i in 1:10) {
print(i ** 2)
}"
# Loop through the values 1-10
#Loop through nums 1-10
for (i in 1:10) {
# Print the squared value of i
#Print the square of each num
print(i ** 2)
}
```
Expand All @@ -92,24 +105,22 @@ for (i in 1:10) {
Create a full testthat file, with test cases for the following R code: "squared_numbers <- function(numbers) {
numbers ^ 2
}"
# testthat file

library(testthat)

context("Test squared_numbers function")
context("squared_numbers()")

# Test 1: Check if function works with a single input
test_that("Squared numbers should work with a single input", {
expect_equal(squared_numbers(2), 4)
test_that("basic squared_numbers() is able to squared number", {
expect_equal(squared_numbers(4), 16)
})

# Test 2: Check if function works with a vector of inputs
test_that("Squared numbers should work with a vector of inputs", {
expect_equal(squared_numbers(c(1, 2, 3)), c(1, 4, 9))
test_that("squared_numbers() result is number", {
expect_type(squared_numbers(4), "numeric")
})

# Test 3: Check if function works with a matrix of inputs
test_that("Squared numbers should work with a matrix of inputs", {
expect_equal(squared_numbers(matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)),
matrix(c(1, 4, 9, 16), nrow = 2, ncol = 2))
test_that("squared_numbers() is able to handle vector input", {
expect_equal(squared_numbers(c(1,3)), c(1,9))
})
```

Expand All @@ -121,7 +132,7 @@ test_that("Squared numbers should work with a matrix of inputs", {
*** ChatGPT input:

Give a good variable name to the result of the following R code: "sapply(1:10, function(i) i ** 2)"
squared_values
squares
```

#### `document_code`
Expand All @@ -132,16 +143,20 @@ squared_values
*** ChatGPT input:

Document, in roxygen2 format, this R function: "square_numbers <- function(numbers) numbers ** 2"
'#' Square Numbers
'#'
'#' Computes the square of a number
'#'
'#' @param numbers the number to be squared
'#' @return the squared number
'#' @export
square_numbers <- function(numbers) {
numbers ** 2
}
#' Square a Numeric Vector
#'
#' Take a numeric vector as an argument and square each element
#'
#' @param numbers A numeric vector
#'
#' @return A numeric vector with each element squared
#'
#' @examples
#' square_numbers(2:10)
#'
#' @export
#'
square_numbers <- function(numbers) numbers ** 2
```

#### `explain_code`
Expand All @@ -154,7 +169,7 @@ square_numbers <- function(numbers) {
Explain the following R code: "for (i in 1:10) {
print(i ** 2)
}"
This code will print the squares of the numbers 1 to 10. The for loop will iterate over the numbers 1 to 10, and for each number, the code will print the result of that number raised to the power of 2 (i.e. the square of that number).
The code is a for loop that prints the square of numbers 1 through 10 (i.e., 1, 4, 9, 16, 25, 36, 49, 64, 81, and 100). The loop starts with i=1 and iterates through 10 with the command "i in 1:10," and the square of each number is printed using the expression "i**2."
```

#### `find_issues_in_code`
Expand All @@ -168,9 +183,7 @@ Find issues or bugs in the following R code: "i <- 0
while (i < 0) {
i <- i - 1
}"
1. The while loop is always false, since the starting value of i is 0 and the code is checking if it is less than 0. It should be while (i > 0).

2. The value of i is not modified inside the loop, so the loop will never terminate. It should be i <- i - 1.
1. The loop condition is incorrect. It should be "i > 0" instead of "i < 0".
```

#### `optimize_code`
Expand All @@ -185,8 +198,9 @@ while (i > 0) {
i <- i - 1
print(i)
}"
for (i in 10:0) {
print(i)
i <- 10
for (i in 10:1) {
print(i-1)
}
```

Expand All @@ -202,7 +216,7 @@ while (i > 0) {
i <- i - 1
print(i)
}"
for(i in 10:1){
for (i in 10:1) {
print(i)
}
```
Expand All @@ -228,9 +242,9 @@ The following environment variables variables can be set to tweak the
behavior, as documented in
<https://beta.openai.com/docs/api-reference/completions/create> .

- `OPENAI_MODEL`; defaults to `"text-davinci-003"`
- `OPENAI_MODEL`; defaults to `"gpt-3.5-turbo"`
- `OPENAI_MAX_TOKENS`; defaults to `256`
- `OPENAI_TEMPERATURE`; defaults to `0.7`
- `OPENAI_TEMPERATURE`; defaults to `1`
- `OPENAI_TOP_P`; defaults to `1`
- `OPENAI_FREQUENCY_PENALTY`; defaults to `0`
- `OPENAI_PRESENCE_PENALTY`; defaults to `0`
Binary file added man/figures/chatgpt_meme.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions man/parse_response.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 81ac647

Please sign in to comment.