Programming
CodeConvert 소개
steloflute
2024. 4. 20. 22:12
google에서 convert go to rust 라고 치면 맨 위에 나오는 사이트이다.
URL: Free Code Converter
AI를 이용해서 프로그램 소스 코드를 다른 프로그래밍 언어로 변환해준다.
지원하는 언어는 C, C++, Common Lisp, Go, Rust, Racket, Java 등 다양하다.
예제로 MNIST를 Go에서 Rust로 변환해봤는데, csv 파일 읽는 공통 부분을 함수로 빼냈다! 대단하다.
let (answer, data) = (&line[0], &line[1..]); 부분도 원래 없는 answer 변수를 사용하고, 배열을 쪼개서 저장하는 한 줄로 묶었다.
다만, sumSqErr는 zip, map 등을 사용한 함수형 rust 코드로 바꿔서 더 느려졌다.
원본 Go:
// squared error, int
// accuracy: 0.9691
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
func square(x int) int {
return x * x
}
func sumSqErr(x, y []int) int {
l := len(x)
if l != len(y) {
log.Fatal("not same size")
}
sum := 0
for i := range x {
sum += square(x[i] - y[i])
}
return sum
}
func main() {
fmt.Println("!")
const fileNameTrain = "mnist_train.csv"
const fileNameTest = "mnist_test.csv"
// train
file, err := os.Open(fileNameTrain)
if err != nil {
log.Fatal(err)
}
sin := bufio.NewScanner(file)
trainData := [][]int{}
for sin.Scan() {
line := sin.Text()
split := strings.Split(line, ",")
data := []int{}
for _, v := range split {
n, err := strconv.ParseInt(v, 10, 64)
if err != nil {
log.Fatal(err)
}
data = append(data, int(n))
}
trainData = append(trainData, data)
}
file.Close()
fmt.Println("train data loaded. rows:", len(trainData))
// test
file, err = os.Open(fileNameTest)
if err != nil {
log.Fatal(err)
}
sin = bufio.NewScanner(file)
nRows := 0
nCorrect := 0
for sin.Scan() {
nRows++
line := sin.Text()
split := strings.Split(line, ",")
data := []int{}
for _, v := range split {
n, err := strconv.ParseInt(v, 10, 64)
if err != nil {
log.Fatal(err)
}
data = append(data, int(n))
}
// fmt.Println("data:", data)
// predict
best := 0
minError := -1
for i, d := range trainData {
error := sumSqErr(data[1:], d[1:])
if minError < 0 || error < minError {
minError = error
best = int(trainData[i][0])
}
}
if best == int(data[0]) {
nCorrect++
}
fmt.Println("predicted:", best, "answer:", data[0], "accuracy:", float64(nCorrect)/float64(nRows))
}
file.Close()
fmt.Println("train data loaded. rows:", nRows, "accuracy:", float64(nCorrect)/float64(nRows))
}
변환 Rust:
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;
fn square(x: i32) -> i32 {
x * x
}
fn sum_sq_err(x: &[i32], y: &[i32]) -> i32 {
if x.len() != y.len() {
panic!("not same size");
}
x.iter()
.zip(y.iter())
.map(|(a, b)| square(a - b))
.sum()
}
fn main() -> Result<(), Box<dyn Error>> {
println!("!");
let file_name_train = "mnist_train.csv";
let file_name_test = "mnist_test.csv";
// train
let train_data = read_csv(file_name_train)?;
println!("train data loaded. rows: {}", train_data.len());
// test
let mut n_rows = 0;
let mut n_correct = 0;
for line in read_csv(file_name_test)? {
n_rows += 1;
let (answer, data) = (&line[0], &line[1..]);
let mut best = 0;
let mut min_error = -1;
for row in &train_data {
let error = sum_sq_err(&data, &row[1..]);
if min_error < 0 || error < min_error {
min_error = error;
best = row[0];
}
}
if best == *answer {
n_correct += 1;
}
println!(
"predicted: {}, answer: {}, accuracy: {}",
best,
answer,
(n_correct as f64) / (n_rows as f64)
);
}
println!(
"train data loaded. rows: {}, accuracy: {}",
n_rows,
(n_correct as f64) / (n_rows as f64)
);
Ok(())
}
fn read_csv(file_name: &str) -> Result<Vec<Vec<i32>>, Box<dyn Error>> {
let path = Path::new(file_name);
let file = File::open(path)?;
let reader = BufReader::new(file);
let mut data = Vec::new();
for line in reader.lines() {
let line = line?;
let values: Vec<i32> = line
.split(',')
.map(|s| i32::from_str(s).unwrap())
.collect();
data.push(values);
}
Ok(data)
}