Crearea unei bănci de întrebări folosind foaia Google, instalatorul și picăturile digitale oceanice

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

Aflați cum să construiți o bancă de întrebări în stil flash-card folosind Google Sheets ca stocare, API-ul instalației R și să o găzduiți pe o picătură digitală oceanică-configurare, implementare și sfaturi.

Motivații

Unul dintre colegii mei a dorit să creeze o întrebare cumulată pentru a -i ajuta pe elevii noștri în subiectul bolii infecțioase și această idee mi -a apărut în cap. De ce nu folosim Google Sheet pentru un loc în care putem stoca întrebările și răspunsurile, apoi avem o altă platformă pentru a găzdui asta? Există multe modalități de a face acest lucru, dar cred că cel mai puțin întrerupt mod (schimbarea unui lucru nu va afecta celelalte părți) este să aveți Google Sheet ca un sistem de stocare, instalator ca API și o picătură digitală pentru ocean pentru a o găzdui! Acesta este un tutorial pas cu pas în crearea unuia.

Obiective:

Sfârșitul în minte

Deci, ceea ce vrem să realizăm la sfârșit este un site în care putem avea un fel de întrebări de studiu a timpului de card flash. În cazul în care avem o întrebare simplă și butonul A pentru a face clic pentru a dezvălui răspunsul, un buton pentru a merge la următoarea întrebare, pentru a sorta la întâmplare întrebările, ca așa …

Dacă sunteți familial cu R sau alte limbaje de programare, toate acestea ar trebui să aibă sens pentru dvs. Dacă nu, este posibil să fie nevoie să înveți un pic de R și unele cunoștințe de codificare. Partea cea mai bună este că acum puteți utiliza LLM pentru a vă ajuta (de exemplu, explicați codul, remediați codul, învățarea codului etc). Rețineți, de asemenea, că unii dintre pași vor necesita o formă de înregistrare și plată (de exemplu, cel mai ieftin ~ 5 $/lună), în special atunci când vine vorba de digitale și contul de ocean digital. Iată, așadar, o listă de instrumente de care aveți nevoie:

  • Patience & persistencedacă nu știți cum să codificați (îmi pare rău, acest tutorial este destinat celor care știu deja și au instalat R). Acest lucru se poate aplica și celor care știu să codeze, dar nu sunt familiarizați cu instalatorul sau oceanul digital.
  • Some coding sau cel puțin lots of copy and pasting
  • Familiar cu Google Sheet
  • Instalat R, plumberau un digital ocean cont (dacă nu creați unul)
  • Au unele ssh, bash cunoştinţe
  • Familiar cu HTML şi CSS (opțional, dar util)
  • Ultimul, dar nu cel din urmă, Be very good with using LLM to help you

Stabiliți -vă întrebările

Pentru a vă configura întrebările, puteți utiliza Google Sheet. Ca așa:

Acesta este doar un exemplu. Rețineți că avem 5 coloane aici. După ce ați creat această foaie Google, asigurați -vă că faceți clic pe Share și schimbați accesul la „Oricine cu linkul poate vizualiza”. Acest lucru este important, deoarece vom folosi acest link pentru a accesa datele din API -ul nostru de instalator. Ca așa:

Apoi copiați linkul și al nostru sheet ID este între /d/ şi /edit. În acest caz, ID -ul nostru arată așa 1iDup4-23ir8Faos2Ml_hvWiWYQGv73aLs7NmhjWDxz9 (FYI, acesta nu este un ID real). Salvați acest ID pentru mai târziu.

Proparare și chestii HTML

Acum trebuie să creăm o API de instalator. Dacă nu știți ce este instalatorul, este un pachet R care vă permite să creați API -uri folosind R. Puteți citi mai multe despre el aici.

Pentru a crea o API de instalator, trebuie să creați un nou fișier R Script (de exemplu, api.R) și adăugați următorul cod:

instalator.R

library(plumber)
library(googlesheets4)
library(dplyr)

# Disable authentication for public sheets
gs4_deauth()

# Configuration
SHEET_ID <- "1iDup4-23ir8Faos2Ml_hvWiWYQGv73aLs7NmhjWDxz9" #### <- this is your google sheet ID

# Global variables for caching
questions_cache <- NULL
last_fetch_time <- 0
cache_duration <- 5 * 60  # 5 minutes in seconds

# Function to fetch questions from Google Sheets
fetch_questions_from_sheet <- function() {
  tryCatch({
    sheet_data <- read_sheet(SHEET_ID, range = "A2:E100", col_names = FALSE)
    
    # Set column names
    names(sheet_data) <- c("question", "answer", "reference", "image_url", "tag")
    
    # Clean and process data
    questions <- sheet_data %>%
      filter(!is.na(question) & !is.na(answer) & 
               question != "" & answer != "") %>%
      mutate(
        id = row_number(),
        question = as.character(question),
        answer = as.character(answer),
        reference = ifelse(is.na(reference), "", as.character(reference)),
        image_url = ifelse(is.na(image_url), "", as.character(image_url)),
        tag = ifelse(is.na(tag), "general", as.character(tag))
      ) %>%
      select(id, question, answer, reference, image_url, tag)
    
    # Update cache
    questions_cache <<- questions
    last_fetch_time <<- as.numeric(Sys.time())
    
    cat("Successfully loaded", nrow(questions), "questions\n")
    return(questions)
    
  }, error = function(e) {
    cat("Error loading from Google Sheets:", e$message, "\n")
    # Return empty data frame with correct structure
    return(data.frame(
      id = integer(0),
      question = character(0),
      answer = character(0),
      reference = character(0),
      image_url = character(0),
      tag = character(0),
      stringsAsFactors = FALSE
    ))
  })
}

# Function to get questions with caching
get_questions <- function() {
  current_time <- as.numeric(Sys.time())
  
  if (is.null(questions_cache) || 
      (current_time - last_fetch_time) > cache_duration) {
    return(fetch_questions_from_sheet())
  }
  
  return(questions_cache)
}

#* Enable CORS
#* @filter cors
cors <- function(req, res) {
  res$setHeader("Access-Control-Allow-Origin", "*")
  res$setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
  res$setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization")
  if (identical(req$REQUEST_METHOD, "OPTIONS")) {
    res$status <- 200
    return(list())
  } else {
    plumber::forward()
  }
}

#* Get all questions (shuffled)
#* @get /api/questions/all
function() {
  tryCatch({
    cat("API call received for all questions\n")
    
    questions <- get_questions()
    cat("Retrieved", nrow(questions), "questions\n")
    
    if (nrow(questions) == 0) {
      cat("No questions found\n")
      return(list(
        success = FALSE,
        error = "No questions found"
      ))
    }
    
    # Shuffle the questions
    shuffled_questions <- questions(sample(nrow(questions)), )
    
    # Convert to list format
    questions_list <- lapply(1:nrow(shuffled_questions), function(i) {
      q <- shuffled_questions(i, )
      list(
        id = as.numeric(q$id),
        question = as.character(q$question),
        answer = as.character(q$answer),
        reference = ifelse(is.na(q$reference) || q$reference == "", "", as.character(q$reference)),
        image_url = ifelse(is.na(q$image_url) || q$image_url == "", "", as.character(q$image_url)),
        tag = as.character(q$tag)
      )
    })
    
    result <- list(
      success = TRUE,
      data = questions_list,
      total = length(questions_list)
    )
    
    cat("Returning", length(questions_list), "shuffled questions\n")
    return(result)
    
  }, error = function(e) {
    cat("Error in all questions endpoint:", e$message, "\n")
    return(list(
      success = FALSE,
      error = paste("Server error:", e$message)
    ))
  })
}

#* Serve the main HTML page
#* @get /
#* @serializer html
function() {
  readLines("public/index.html", warn = FALSE) %>% paste(collapse = "\n")
}

#* Serve CSS file
#* @get /styles.css
#* @serializer contentType list(type="text/css")
function() {
  readLines("public/styles.css", warn = FALSE) %>% paste(collapse = "\n")
}

# Cache will be initialized on first API call

Pasul 1: Salvați cele de mai sus ca plumber.R.

qbank_api.r

#!/usr/bin/env Rscript

library(plumber)

HOST <- "0.0.0.0"
PORT <- 8000

cat("Starting Plumber API...\n")
cat("Available at: http://localhost:", PORT, "\n\n")

# Create API from plumber.R file
api <- plumber::plumb("plumber.R")
api$run(host = HOST, port = PORT)

Pasul 2: Salvați codul de mai sus ca qbank_api.R.
Pasul 3: Creați un folder numit public și creați două fișiere în el:
index.html şi
styles.css.
Pasul 4: rulați qbank_api.R în consola dvs. R. Acest lucru va începe API -ul instalatorului și ar trebui să vedeți așa ceva:

Pasul 5: accesați browserul și navigatorul la http://0.0.0.0:8000/ sau http://localhost:8000/. Ar trebui să vedeți o simplă pagină HTML, la fel ca ceea ce am văzut în finalul nostru

Dacă ați ajuns aici și totul funcționează, felicitări! Ați creat o API pentru banca de întrebări la nivel local! Acum, dacă doriți acces la el de oriunde, trebuie să îl găzduiți undeva. Dacă nu aveți nevoie de asta (sunteți bine cu banca de întrebări găzduite local), atunci ați terminat! 🙌

Găzduiește -l cu oceanul digital

Aceasta este partea care poate fi puțin frustrantă să fiu sincer. Sper să ofer un ghid pas cu pas aici. Aceasta este, de asemenea, o modalitate pentru mine să iau notă pentru ca viitorul să mă refer. Lucrurile se actualizează tot timpul, până când citiți acest lucru, lucrurile s -ar putea să nu se mai aplice, iar picăturile pe care am creat -o pentru demo ar fi fost distrusă, dar să dăm tot ce este mai bun!

Pasul 1. Creați un cont digital ocean: Dacă nu aveți unul, mergeți la Digital Ocean și creați un cont. Este posibil să fie nevoie să adăugați o metodă de plată.

Pasul 2.

  • Creați un proiect: După conectarea, creați un nou proiect. Îl poți numi ceva de genul „Bank de întrebări” sau orice îți place.
  • Creați o picătură: Du -te la create apoi faceți clic pe droplet. Alegeți următoarele opțiuni:
    • Regiunea centrului de date: Alege o regiune aproape de tine.
    • Imagine: Alege Ubuntu 22.04 (LTS) x64 (Acest lucru este important !!! Nu am reușit să instalez R cu ubbuntu 24)
    • Plan: Alegeți cel mai ieftin (de exemplu, Basic Plan cu 1 GB RAM)
  • Autentificare: Utilizați tastele SSH dacă le aveți configurate sau utilizați o parolă. Parola poate fi cea mai ușoară pentru un starter
  • Finalizați și creați: Faceți clic pe Create Droplet.

Vei vedea apoi așa ceva:

Pasul 3. Conectați -vă la picătura dvs.:

Pasul 4. Instalați R și instalator:

# install R, dependencies, libraries
sudo apt update
sudo apt install r-base r-base-dev
sudo apt install -y libcurl4-openssl-dev libssl-dev libxml2-dev libsodium-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev build-essential libgit2-dev libssh2-1-dev
Rscript -e "install.packages(c('tidyverse', 'plumber', 'rvest', 'googlesheets4'), repos='https://cran.rstudio.com/', dependencies=TRUE)"

Copiați și lipiți cele de mai sus în terminalul dvs. după ce ați fost ssh-ed în picăturile dvs. Atenție că acest lucru poate dura cândva, de asemenea, unele intrări manualeîn așteptarea acestora, vă rugăm să nu ezitați să mergeți la pasul 5 pentru a încărca fișierele necesare

De asemenea, luați notă, că, dacă aveți probleme de instalare a celor de mai sus, s -ar putea să fi rămas fără spațiu RAM sau pe disc. Puteți verifica spațiul pe disc cu df -h și Ram cu free -h. Dacă ați rămas fără spațiu, este posibil să fie necesar să redimensionați picăturile sau să ștergeți unele fișiere.

Pasul 5. Încărcați fișierele dvs.:

  • Utilizare sftp sau filezilla pentru a încărca fișierele. Mai jos este un exemplu de utilizare sftp:
sftp root@your_droplet_ip_address
sftp> put qbank_api.R
sftp> put plumber.R
sftp> put public/index.html
sftp> put public/styles.css
sftp> exit

Asigurați -vă că calea către fișier este specificată corect.

Iată un link către ZIP pentru toate fișierele de care aveți nevoie pentru a obține un produs viabil minim. 🤞

  • Dacă utilizați filezillaputeți trage și arunca fișierele în directorul de origine al picăturii. Asigurați -vă că fișierele sunt în același director ca plumber.R şi qbank_api.R.

Pasul 6. Rulează API -ul:

sudo nano /etc/systemd/system/qbank-api.service

(Unit)
Description=QBank API Service
After=network.target

(Service)
Type=simple
User=root
WorkingDirectory=/home/idqbank/
ExecStart=/usr/bin/Rscript qbank_api.R
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=qbank-api

(Install)
WantedBy=multi-user.target

Ia notă pe WorkingDirectory şi ExecStart linii. Trebuie să schimbați calea către locul în care v -ați încărcat fișierele. De exemplu, dacă ați încărcat fișierele dvs. /home/your_username/qbank/atunci trebuie să vă schimbați WorkingDirectory=/home/idqbank/ la WorkingDirectory=/home/your_username/qbank/ şi ExecStart=/usr/bin/Rscript qbank_api.R la ExecStart=/usr/bin/Rscript /home/your_username/qbank/qbank_api.R.

# Reload systemd to recognize the new service
sudo systemctl daemon-reload

# Enable the service to start on boot
sudo systemctl enable qbank-api.service

# Start the service now
sudo systemctl start qbank-api.service

Acest lucru va crea un serviciu SystemD care va rula API -ul dvs. în fundal. Doriți să vă asigurați dacă picăturile repornește din anumite motive, doriți ca API -ul dvs. să repornească automat. Prin urmare, pasul de mai sus este important.

Pasul 7. Verificați dacă API -ul funcționează:

sudo systemctl status qbank-api.service

Ar trebui să vezi așa ceva:

Pasul 8. Accesați API -ul dvs.: Acum puteți accesa API -ul dvs. de oriunde! Du -te doar la http://your_droplet_ip_address:8000/ în browserul tău. Ar trebui să vedeți aceeași pagină HTML ca înainte. Asigurați -vă că includeți port Ai specificat în qbank_api.R fișier (de exemplu, 8000) Nu va funcționa cu setarea curentă dacă nu.

Dacă sunteți interesat să eliminați numărul portului, puteți configura un proxy invers folosind Nginx. Acest lucru este ceva mai avansat și dincolo de sfera de aplicare a acestui tutorial, dar puteți găsi multe tutoriale online despre cum să faceți asta.

Rețineți că folosim http nu https. Ceea ce înseamnă că nu avem încă o conexiune sigură. Dacă doriți să aveți o conexiune sigură, trebuie să configurați un certificat SSL. Nu vom trece prin asta pe acest blog.

Asta este! Dacă ai ajuns până acum, felicitări! 👏 Ați creat cu succes o bancă de întrebări folosind Google Shey, Instalație și Digital Ocean Proplet. Acum puteți adăuga mai multe întrebări pe foaia dvs. Google și acestea vor fi disponibile automat în API -ul dvs., după 5 minutes de schimbări.

Sfaturi

Dacă ați folosit deja LLM (de exemplu, Chatgpt, Claude, Gemini etc), fantastic! Dacă nu ați făcut -o, vă recomand cu mare drag să o utilizați pentru a vă ajuta cu codificarea, depanarea și învățarea. Iată câteva sfaturi:

  • Explaination: Toate acestea îți par străine? Copiați și lipiți în LLM și întrebați explain this code to me
  • Follow up on it: Dacă încă nu înțelegeți ceva, cereți LLM să -l explice mai departe.
  • Debugging: Dacă aveți o eroare, copiați și lipiți mesajul de eroare în LLM și întrebați what does this error mean? sau how do I fix this error?
    • Screen Caputure: Încă nu este sigur? Capturați ecranului ceea ce vedeți, atașați o poză pe LLM și întrebați!
    • Fetch URL: Confuz cu ceea ce am scris aici? Lipiți această adresă URL și întrebați what does this blog mean? sau how do I do this?
  • Interesat în SSL cert şi nginx proxy invers? Rugați -l pe LLM să vă explice sau să întrebați how do I set up SSL certificate for my droplet? sau how do I set up nginx reverse proxy for my droplet?.
  • Having the end in mind helps: Asigurați -vă că rulează local înainte de a -l găzdui. Dacă nu rulează la nivel local, nu va rula pe server.

Oportunități de îmbunătățire și alte idei

  • Cu siguranță trebuie să creați certificat SSL pentru o conexiune securizată. Puteți utiliza Let’s Encrypt pentru a crea un certificat SSL gratuit.
  • Aceasta nu trebuie să fie o bancă de întrebări. Ce zici de fabrica de idei? Tabloul de bord de un fel? Metrici? Okr? Folosește -ți imaginația!

Lecții învățate

  • Încercat pe picături multipel pentru a instala R, dar numai Ubuntu 22.04 funcționează deocamdată.
  • Dacă aveți probleme de instalare R, s -ar putea să fi rămas fără spațiu RAM sau pe disc.

Dacă vă place acest articol:

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.