GCP VM에서 MariaDB 설정
1. MariaDB 설정 파일 수정
/etc/mysql/mariadb.conf.d/50-server.cnf
#bind-address = 127.0.0.1
bind-address = 0.0.0.0
# [mysqld] 항목 아래 추가
skip-name-resolve
2. MariaDB 재시작
sudo systemctl restart mariadb
3. 외부 원격 접속 권한 부여
GREANT ALL PRIVILEGES ON backend.* TO '{사용자명}'@'%' IDENTIFIED BY '{비밀번호}';
FLUSH PRIVILEGES;
루커스튜디오 실습
flask + Chart.js를 이용한 웹 대시보드 실습
소스
app.py
from flask import Flask, render_template, jsonify
from textData5 import text_data
app = Flask(__name__)
@app.route('/')
def index():
# 텍스트 데이터와 그래프 데이터를 전달
return render_template('index.html', text_data=text_data)
@app.route('/data')
def get_data():
# 그래프 데이터를 JSON으로 반환
return jsonify(text_data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001, debug=True)
textData.py
text_data = {
"academic_performance": {
"data": {
"semesters": [
"2025-1학기 중간고사", "2025-1학기 기말고사", "2025-2학기 중간고사", "2025-2학기 기말고사"
],
"gpa": [2.5, 2.8, 3.2, 3.6],
"math_score": [70, 75, 80, 85],
"english_score": [65, 70, 78, 82]
},
"description": {
"gpa": (
"평균 학점: 학생의 학점은 지속적으로 상승하고 있으며, 학업 성취도가 점점 향상되고 있습니다.\n"
"특히 최근 학기에서 3.5 이상을 기록하며 우수한 성적을 보였습니다.\n"
"학습 조언: 꾸준한 성적 향상을 위해 현재의 학습 방법을 유지하면서, 부족한 과목을 보완하는 전략을 세우는 것이 좋습니다.\n"
),
"math_score": (
"수학 성적: 수학 점수는 학기별로 꾸준히 상승하고 있으며, 학생의 문제 해결 능력이 향상되고 있음을 보여줍니다.\n"
"학습 조언: 수학적 사고력 강화를 위해 추가적인 문제 풀이와 응용 문제 학습을 병행하면 더욱 좋은 성과를 낼 수 있습니다.\n"
),
"english_score": (
"영어 성적: 영어 점수 또한 꾸준히 증가하고 있으며, 특히 최근 학기에서 큰 폭의 성장을 보였습니다.\n"
"학습 조언: 리딩과 스피킹 연습을 병행하여 실전 감각을 키우고, 영어 원서를 활용한 학습법을 적용해보는 것도 좋은 방법입니다.\n"
)
}
},
"study_habits": {
"data": {
"semesters": [
"2025-1학기 중간고사", "2025-1학기 기말고사", "2025-2학기 중간고사", "2025-2학기 기말고사"
],
"study_hours_per_week": [10, 12, 15, 18],
"attendance_rate": [85, 88, 92, 95]
},
"description": {
"study_hours_per_week": (
"주간 공부 시간: 학생의 주간 공부 시간이 점차 증가하고 있으며, 이는 성적 향상에 긍정적인 영향을 주고 있습니다.\n"
"학습 조언: 효율적인 시간 관리를 통해 집중적인 학습 시간을 확보하고, 과목별로 균형 잡힌 공부 계획을 세우는 것이 중요합니다.\n"
),
"attendance_rate": (
"출석률: 출석률이 점진적으로 상승하고 있으며, 학업에 대한 집중력이 향상되고 있음을 보여줍니다.\n"
"학습 조언: 꾸준한 출석을 유지하면서 적극적인 수업 참여와 복습을 통해 학습 효과를 극대화하는 것이 바람직합니다.\n"
)
}
}
}
templates/index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Financial Analysis Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
color: #333;
}
h1 {
text-align: center;
padding: 20px;
background-color: #333;
color: white;
}
section {
margin: 20px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h2 {
color: #333;
margin-bottom: 10px;
}
.analysis-text {
font-size: 16px;
line-height: 1.6;
margin-bottom: 20px;
padding: 15px;
border-left: 5px solid #333;
background-color: #f9f9f9;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
canvas {
margin: 20px 0;
}
.chart-container {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.chart-box {
width: 45%;
margin-bottom: 20px;
}
footer {
text-align: center;
padding: 10px;
background-color: #333;
color: white;
position: fixed;
width: 100%;
bottom: 0;
}
</style>
</head>
<body>
<h1>OO학생 성적 분석</h1>
<section>
<h2>1. 학점 분석</h2>
<div class="analysis-text">{{ text_data.academic_performance.description.gpa }}</div>
<div class="analysis-text">{{ text_data.academic_performance.description.math_score }}</div>
<div class="analysis-text">{{ text_data.academic_performance.description.english_score }}</div>
<div class="chart-container">
<div class="chart-box">
<canvas id="academicPerformanceGpaChart" width="400" height="200"></canvas>
</div>
<div class="chart-box">
<canvas id="academicPerformanceChart" width="400" height="200"></canvas>
</div>
</div>
</section>
<section>
<h2>2. 공부 습관 분석</h2>
<div class="analysis-text">{{ text_data.study_habits.description.study_hours_per_week }}</div>
<div class="analysis-text">{{ text_data.study_habits.description.attendance_rate }}</div>
<div class="chart-container">
<div class="chart-box">
<canvas id="studyHabitsChart" width="400" height="200"></canvas>
</div>
<div class="chart-box">
<canvas id="studyHoursVsGpaCtx" width="400" height="200"></canvas>
</div>
</div>
</section>
<footer>
© 2025 박현우
</footer>
<script>
const textData = {{ text_data | tojson | safe }};
const academicPerformanceCtx = document.getElementById('academicPerformanceChart').getContext('2d');
new Chart(academicPerformanceCtx, {
type: 'line',
data: {
labels: textData.academic_performance.data.semesters,
datasets: [
{
label: '수학',
data: textData.academic_performance.data.math_score,
borderColor: 'rgba(75, 192, 192, 1)',
fill: false
},
{
label: '영어',
data: textData.academic_performance.data.english_score,
borderColor: 'rgba(255, 99, 132, 1)',
fill: false
}
]
},
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: '기간'
}
},
y: {
title: {
display: true,
text: '점수 (점)'
}
}
}
}
});
const academicPerformanceGpaCtx = document.getElementById('academicPerformanceGpaChart').getContext('2d');
new Chart(academicPerformanceGpaCtx, {
type: 'line',
data: {
labels: textData.academic_performance.data.semesters,
datasets: [
{
label: '학점',
data: textData.academic_performance.data.gpa,
borderColor: 'rgba(75, 192, 192, 1)',
fill: false
},
]
},
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: '기간'
}
},
y: {
title: {
display: true,
text: '점수 (점)'
}
}
}
}
});
const studyHabitsCtx = document.getElementById('studyHabitsChart').getContext('2d');
new Chart(studyHabitsCtx, {
type: 'line',
data: {
labels: textData.study_habits.data.semesters,
datasets: [
{
label: '주간 공부 시간',
data: textData.study_habits.data.study_hours_per_week,
borderColor: 'rgba(75, 192, 192, 1)',
fill: false,
yAxisID: 'y'
},
{
label: '출석률 (%)',
data: textData.study_habits.data.attendance_rate,
borderColor: 'rgba(255, 99, 132, 1)',
fill: false,
yAxisID: 'y1'
}
]
},
options: {
responsive: true,
scales: {
x: {
title: {
display: true,
text: '기간'
}
},
y: {
title: {
display: true,
text: '주간 공부 시간'
},
position: 'left',
beginAtZero: true
},
y1: {
title: {
display: true,
text: '출석률 (%)'
},
position: 'right',
beginAtZero: true,
grid: {
drawOnChartArea: false
}
}
}
}
});
const studyHoursVsGpaCtx = document.getElementById('studyHoursVsGpaCtx').getContext('2d');
new Chart(studyHoursVsGpaCtx, {
type: 'scatter',
data: {
datasets: [{
label: '공부 시간 vs GPA',
data: textData.study_habits.data.study_hours_per_week.map((hours, index) => ({
x: hours,
y: textData.academic_performance.data.gpa[index]
})),
backgroundColor: 'rgba(75, 192, 192, 1)'
}]
},
options: {
responsive: true,
scales: {
x: {
title: { display: true, text: '주간 공부 시간' },
type: 'linear',
position: 'bottom'
},
y: {
title: { display: true, text: 'GPA' }
}
}
}
});
</script>
</body>
</html>
'회고' 카테고리의 다른 글
[멋쟁이사자처럼 그로스마케팅 부트캠프] 24일차 회고 (1) | 2025.03.10 |
---|---|
[멋쟁이사자처럼 그로스마케팅 부트캠프] 23일차 회고 (3) | 2025.03.07 |
[멋쟁이사자처럼 그로스마케팅 부트캠프] 21일차 회고 (1) | 2025.03.05 |
[멋쟁이사자처럼 그로스마케팅 부트캠프] 20일차 회고 (2) | 2025.03.04 |
[멋쟁이사자처럼 그로스마케팅 부트캠프] 19일차 회고 (1) | 2025.02.28 |