說明:
vue+d3js+fastapi實現天氣柱狀圖折線圖餅圖
效果圖:
step0:postman
1. 生成天氣數據(POST請求):URL: http://localhost:8000/generate-data/?year=2024&month=3&seed=42
方法: POST
Headers:Content-Type: application/json
成功響應示例:
{"status": "success","message": "成功生成31條天氣數據","year": 2024,"month": 3
}2. 查詢天氣數據(GET請求):URL: http://localhost:8000/weather-data/?year=2024&month=4
方法: GET
成功響應示例:{"status": "success","count": 31,"year": 2024,"month": 3,"data": [{"record_date": "2024-03-01","temperature": 16.4,"humidity": 72,"precipitation": 0.0,"wind_speed": 7.2,"weather_condition": "Cloudy"},{"record_date": "2024-03-31","temperature": 17.3,"humidity": 62,"precipitation": 3.8,"wind_speed": 1.4,"weather_condition": "Rain"}]
}
step1:sql
CREATE TABLE weather_data (id INT AUTO_INCREMENT PRIMARY KEY,record_date DATE NOT NULL,temperature DECIMAL(4,1) NOT NULL, -- 格式:-99.9 到 99.9humidity TINYINT UNSIGNED NOT NULL, -- 范圍:0-100precipitation DECIMAL(5,1) NOT NULL, -- 最大999.9mmwind_speed DECIMAL(4,1) NOT NULL, -- 最大99.9m/sweather_condition VARCHAR(50) NOT NULL, -- 修改列名INDEX (record_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;select *from weather_data;
step2:python test
C:\Users\wangrusheng\PycharmProjects\FastAPIProject1\hello.py
import random
from datetime import date
from decimal import Decimal
import calendar
import pymysql.cursors
import json
# 數據庫配置(根據實際情況修改)
DB_CONFIG = {'host': 'localhost','user': 'root','password': '123456','db': 'db_school','charset': 'utf8mb4','cursorclass': pymysql.cursors.DictCursor
}def generate_temperature(rng, min_temp=10.0, max_temp=20.0):"""生成溫度數據(均勻分布)"""temp = rng.uniform(min_temp, max_temp)return round(temp, 1)def generate_humidity(rng):"""生成濕度數據(正態分布)"""humidity = rng.gauss(60, 15)humidity = max(0, min(humidity, 100))return int(round(humidity))def generate_precipitation(rng):"""生成降水量數據(20%概率下雨)"""if rng.random() < 0.2:amount = rng.expovariate(1 / 5.0) # 平均5mmamount = max(0.1, min(amount, 30.0))return round(amount, 1)return 0.0def generate_wind_speed(rng):"""生成風速數據(伽馬分布)"""speed = rng.gammavariate(2, 2)speed = max(0.0, min(speed, 20.0))return round(speed, 1)def get_weather_condition(temperature, precipitation, humidity, rng):"""根據天氣參數判斷天氣狀況"""if precipitation > 0:return 'Snow' if temperature < 3.0 else 'Rain'if humidity >= 70:return 'Cloudy'if humidity <= 30:return 'Sunny'return rng.choice(['Partly Cloudy', 'Mostly Cloudy'])def generate_monthly_weather_data(year, month, rng=None):"""生成整月天氣數據"""if rng is None:rng = random.Random()_, num_days = calendar.monthrange(year, month)data = []for day in range(1, num_days + 1):record_date = date(year, month, day)temperature = generate_temperature(rng)humidity = generate_humidity(rng)precipitation = generate_precipitation(rng)wind_speed = generate_wind_speed(rng)condition = get_weather_condition(temperature, precipitation, humidity, rng)data.append({'record_date': record_date,'temperature': temperature,'humidity': humidity,'precipitation': precipitation,'wind_speed': wind_speed,'weather_condition': condition})return datadef insert_weather_data(data):"""批量插入天氣數據到數據庫"""connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor() as cursor:sql = """INSERT INTO weather_data (record_date, temperature, humidity, precipitation, wind_speed, weather_condition)VALUES (%s, %s, %s, %s, %s, %s)"""params = [(d['record_date'],d['temperature'],d['humidity'],d['precipitation'],d['wind_speed'],d['weather_condition'])for d in data]cursor.executemany(sql, params)connection.commit()return len(data)except Exception as e:connection.rollback()raise efinally:connection.close()def get_weather_data(year: int, month: int) -> list:"""從數據庫獲取指定年月的天氣數據并轉換為JSON兼容格式"""connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor() as cursor:sql = """SELECT record_date, temperature, humidity, precipitation, wind_speed, weather_conditionFROM weather_dataWHERE YEAR(record_date) = %s AND MONTH(record_date) = %sORDER BY record_date"""cursor.execute(sql, (year, month))results = cursor.fetchall()# 轉換日期和數值類型for record in results:record['record_date'] = record['record_date'].isoformat()# 處理Decimal類型(如果存在)for key in ['temperature', 'precipitation', 'wind_speed']:if isinstance(record[key], Decimal):record[key] = float(record[key])return resultsfinally:connection.close()if __name__ == '__main__':# 示例:生成并插入2024年4月的天氣數據year = 2024month = 4# 創建帶種子的隨機生成器(保證結果可復現)rng = random.Random(42)try:# 生成模擬數據weather_data = generate_monthly_weather_data(year, month, rng)# 插入數據庫# inserted_count = insert_weather_data(weather_data)# print(f"成功插入{inserted_count}條天氣數據")# 獲取并打印JSON數據weather_json = get_weather_data(year, month)print(json.dumps(weather_json, indent=2, ensure_ascii=False))except Exception as e:print(f"操作失敗: {str(e)}")
step3:python fastapi
C:\Users\wangrusheng\PycharmProjects\FastAPIProject1\main.py
from fastapi import FastAPI, HTTPException, Query
from datetime import date
from decimal import Decimal
from typing import Optional
import random
import calendar
import pymysql.cursors
import json
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# CORS配置
app.add_middleware(CORSMiddleware,allow_origins=["*"],allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)
# 數據庫配置(根據實際情況修改)
DB_CONFIG = {'host': 'localhost','user': 'root','password': '123456','db': 'db_school','charset': 'utf8mb4','cursorclass': pymysql.cursors.DictCursor
}# 以下保持原有函數定義不變(generate_temperature、generate_humidity等)
# [原有函數定義區,保持與問題中完全相同的函數實現]def generate_temperature(rng, min_temp=10.0, max_temp=20.0):"""生成溫度數據(均勻分布)"""temp = rng.uniform(min_temp, max_temp)return round(temp, 1)def generate_humidity(rng):"""生成濕度數據(正態分布)"""humidity = rng.gauss(60, 15)humidity = max(0, min(humidity, 100))return int(round(humidity))def generate_precipitation(rng):"""生成降水量數據(20%概率下雨)"""if rng.random() < 0.2:amount = rng.expovariate(1 / 5.0) # 平均5mmamount = max(0.1, min(amount, 30.0))return round(amount, 1)return 0.0def generate_wind_speed(rng):"""生成風速數據(伽馬分布)"""speed = rng.gammavariate(2, 2)speed = max(0.0, min(speed, 20.0))return round(speed, 1)def get_weather_condition(temperature, precipitation, humidity, rng):"""根據天氣參數判斷天氣狀況"""if precipitation > 0:return 'Snow' if temperature < 3.0 else 'Rain'if humidity >= 70:return 'Cloudy'if humidity <= 30:return 'Sunny'return rng.choice(['Partly Cloudy', 'Mostly Cloudy'])def generate_monthly_weather_data(year, month, rng=None):"""生成整月天氣數據"""if rng is None:rng = random.Random()_, num_days = calendar.monthrange(year, month)data = []for day in range(1, num_days + 1):record_date = date(year, month, day)temperature = generate_temperature(rng)humidity = generate_humidity(rng)precipitation = generate_precipitation(rng)wind_speed = generate_wind_speed(rng)condition = get_weather_condition(temperature, precipitation, humidity, rng)data.append({'record_date': record_date,'temperature': temperature,'humidity': humidity,'precipitation': precipitation,'wind_speed': wind_speed,'weather_condition': condition})return datadef insert_weather_data(data):"""批量插入天氣數據到數據庫"""connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor() as cursor:sql = """INSERT INTO weather_data (record_date, temperature, humidity, precipitation, wind_speed, weather_condition)VALUES (%s, %s, %s, %s, %s, %s)"""params = [(d['record_date'],d['temperature'],d['humidity'],d['precipitation'],d['wind_speed'],d['weather_condition'])for d in data]cursor.executemany(sql, params)connection.commit()return len(data)except Exception as e:connection.rollback()raise efinally:connection.close()def get_weather_data(year: int, month: int) -> list:"""從數據庫獲取指定年月的天氣數據并轉換為JSON兼容格式"""connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor() as cursor:sql = """SELECT record_date, temperature, humidity, precipitation, wind_speed, weather_conditionFROM weather_dataWHERE YEAR(record_date) = %s AND MONTH(record_date) = %sORDER BY record_date"""cursor.execute(sql, (year, month))results = cursor.fetchall()# 轉換日期和數值類型for record in results:record['record_date'] = record['record_date'].isoformat()# 處理Decimal類型(如果存在)for key in ['temperature', 'precipitation', 'wind_speed']:if isinstance(record[key], Decimal):record[key] = float(record[key])return resultsfinally:connection.close()@app.post("/generate-data/")
async def generate_weather_data(year: int = Query(..., ge=2000, le=2100, description="年份"),month: int = Query(..., ge=1, le=12, description="月份"),seed: Optional[int] = Query(None, description="隨機種子(可選)")
):"""生成并插入指定月份的天氣數據"""try:rng = random.Random(seed) if seed else random.Random()weather_data = generate_monthly_weather_data(year, month, rng)inserted_count = insert_weather_data(weather_data)return {"status": "success","message": f"成功生成{inserted_count}條天氣數據","year": year,"month": month}except ValueError as e:raise HTTPException(status_code=400, detail=str(e))except Exception as e:raise HTTPException(status_code=500, detail=f"數據庫操作失敗: {str(e)}")@app.get("/weather-data/")
async def get_weather(year: int = Query(..., ge=2000, le=2100, description="年份"),month: int = Query(..., ge=1, le=12, description="月份")
):"""獲取指定月份的天氣數據"""try:data = get_weather_data(year, month)return {"status": "success","count": len(data),"year": year,"month": month,"data": data}except Exception as e:raise HTTPException(status_code=500, detail=f"數據查詢失敗: {str(e)}")if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)
step4:vue
C:\Users\wangrusheng\PycharmProjects\untitled3\src\views\Lottery.vue
<template><div><div class="controls"><input v-model.number="year" type="number" placeholder="年份"><input v-model.number="month" type="number" placeholder="月份" min="1" max="12"><button @click="fetchData">查詢</button><button @click="generateData">生成數據</button></div><div class="charts-container"><div class="chart-box"><h3>每日溫度柱狀圖</h3><div ref="barChart" class="chart"></div></div><div class="chart-box"><h3>溫度趨勢折線圖</h3><div ref="lineChart" class="chart"></div></div><div class="chart-box"><h3>天氣狀況分布餅圖</h3><div ref="pieChart" class="chart"></div></div></div></div>
</template><script>
import * as d3 from 'd3';
import axios from 'axios';export default {data() {return {weatherData: [],year: null,month: null};},methods: {async fetchData() {if (!this.validateInput()) return;try {const response = await axios.get('http://localhost:8000/weather-data/', {params: { year: this.year, month: this.month }});this.weatherData = response.data.data;this.redrawCharts();} catch (error) {this.handleError(error, '查詢');}},async generateData() {if (!this.validateInput()) return;try {const response = await axios.post('http://localhost:8000/generate-data/', null, {params: { year: this.year, month: this.month, seed: 42 },headers: { 'Content-Type': 'application/json' }});alert(`生成成功:${response.data.message}`);await this.fetchData();} catch (error) {this.handleError(error, '生成');}},validateInput() {if (!this.year || !this.month) {alert('請填寫年份和月份');return false;}if (this.month < 1 || this.month > 12) {alert('月份必須為1-12');return false;}return true;},handleError(error, operation) {console.error(`${operation}失敗:`, error);alert(`${operation}失敗,請檢查控制臺`);},redrawCharts() {this.clearCharts();this.drawBarChart();this.drawLineChart();this.drawPieChart();},clearCharts() {[this.$refs.barChart, this.$refs.lineChart, this.$refs.pieChart].forEach(ref => ref.innerHTML = '');},// 各圖表繪制方法(保持原有實現,開頭添加清除邏輯)// 繪制柱狀圖drawBarChart() {const margin = { top: 30, right: 30, bottom: 50, left: 60 };const width = 800 - margin.left - margin.right;const height = 400 - margin.top - margin.bottom;const svg = d3.select(this.$refs.barChart).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', `translate(${margin.left},${margin.top})`);// 創建比例尺const x = d3.scaleBand().domain(this.weatherData.map(d => d.record_date)).range([0, width]).padding(0.2);const y = d3.scaleLinear().domain([0, d3.max(this.weatherData, d => d.temperature)]).range([height, 0]);// 添加柱狀svg.selectAll("rect").data(this.weatherData).join("rect").attr("x", d => x(d.record_date)).attr("y", d => y(d.temperature)).attr("width", x.bandwidth()).attr("height", d => height - y(d.temperature)).attr("fill", "#4CAF50");// 添加坐標軸svg.append("g").attr("transform", `translate(0,${height})`).call(d3.axisBottom(x).tickValues(x.domain().filter((d,i) => !(i%5))));svg.append("g").call(d3.axisLeft(y));// 添加標簽svg.append("text").attr("transform", `translate(${width/2}, ${height + 40})`).style("text-anchor", "middle").text("日期");svg.append("text").attr("transform", "rotate(-90)").attr("y", 0 - margin.left).attr("x",0 - (height / 2)).attr("dy", "1em").style("text-anchor", "middle").text("溫度(℃)");},// 繪制折線圖drawLineChart() {const margin = { top: 30, right: 30, bottom: 50, left: 60 };const width = 800 - margin.left - margin.right;const height = 400 - margin.top - margin.bottom;const svg = d3.select(this.$refs.lineChart).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', `translate(${margin.left},${margin.top})`);// 創建比例尺const x = d3.scaleBand().domain(this.weatherData.map(d => d.record_date)).range([0, width]);const y = d3.scaleLinear().domain([d3.min(this.weatherData, d => d.temperature) - 2, d3.max(this.weatherData, d => d.temperature) + 2]).range([height, 0]);// 創建折線生成器const line = d3.line().x(d => x(d.record_date) + x.bandwidth()/2).y(d => y(d.temperature));// 繪制折線svg.append("path").datum(this.weatherData).attr("fill", "none").attr("stroke", "#2196F3").attr("stroke-width", 2).attr("d", line);// 添加坐標軸svg.append("g").attr("transform", `translate(0,${height})`).call(d3.axisBottom(x).tickValues(x.domain().filter((d,i) => !(i%5))));svg.append("g").call(d3.axisLeft(y));},// 繪制餅圖drawPieChart() {const width = 400;const height = 400;const radius = Math.min(width, height) / 2;const svg = d3.select(this.$refs.pieChart).append('svg').attr('width', width).attr('height', height).append('g').attr('transform', `translate(${width/2},${height/2})`);// 統計天氣狀況const data = Array.from(d3.rollup(this.weatherData,v => v.length,d => d.weather_condition),([name, value]) => ({name, value}));// 創建顏色比例尺const color = d3.scaleOrdinal().domain(data.map(d => d.name)).range(d3.schemeCategory10);// 餅圖生成器const pie = d3.pie().value(d => d.value);// 弧形生成器const arc = d3.arc().innerRadius(0).outerRadius(radius);// 繪制扇形const arcs = svg.selectAll("arc").data(pie(data)).enter().append("g").attr("class", "arc");arcs.append("path").attr("d", arc).attr("fill", d => color(d.data.name)).attr("stroke", "white").style("stroke-width", "2px");// 添加標簽arcs.append("text").attr("transform", d => `translate(${arc.centroid(d)})`).attr("text-anchor", "middle").text(d => d.data.name);}}
};
</script><style>
.controls {padding: 1rem;display: flex;gap: 1rem;align-items: center;
}.controls input {padding: 0.5rem;border: 1px solid #ddd;border-radius: 4px;width: 120px;
}.controls button {padding: 0.5rem 1rem;background: #2196F3;color: white;border: none;border-radius: 4px;cursor: pointer;
}.controls button:hover {background: #1976D2;
}.charts-container {display: flex;flex-direction: column;gap: 2rem;padding: 2rem;
}.chart-box {background: white;padding: 1rem;border-radius: 8px;box-shadow: 0 2px 4px rgba(0,0,0,0.1);width: 100%;
}.chart-box h3 {margin: 0 0 1rem;color: #333;
}.chart {width: 100%;height: 400px;
}
</style>
end
//我是分割線
step101: old vue
下面的代碼修改:1.年份 月份 改為可選,
2.新增兩個按鈕,查詢和添加
3.查詢和添加,需要做網絡請求
4.三個圖表 需要垂直排列1. 生成天氣數據(POST請求):URL: http://localhost:8000/generate-data/?year=2024&month=3&seed=42
方法: POST
Headers:Content-Type: application/json
成功響應示例:
{"status": "success","message": "成功生成31條天氣數據","year": 2024,"month": 3
}<template><div class="charts-container"><div class="chart-box"><h3>每日溫度柱狀圖</h3><div ref="barChart" class="chart"></div></div><div class="chart-box"><h3>溫度趨勢折線圖</h3><div ref="lineChart" class="chart"></div></div><div class="chart-box"><h3>天氣狀況分布餅圖</h3><div ref="pieChart" class="chart"></div></div></div>
</template><script>
import * as d3 from 'd3';
import axios from 'axios';export default {data() {return {weatherData: []};},async mounted() {try {const response = await axios.get('http://localhost:8000/weather-data/?year=2024&month=4');this.weatherData = response.data.data;this.drawBarChart();this.drawLineChart();this.drawPieChart();} catch (error) {console.error('數據獲取失敗:', error);}},methods: {// 繪制柱狀圖drawBarChart() {const margin = { top: 30, right: 30, bottom: 50, left: 60 };const width = 800 - margin.left - margin.right;const height = 400 - margin.top - margin.bottom;const svg = d3.select(this.$refs.barChart).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', `translate(${margin.left},${margin.top})`);// 創建比例尺const x = d3.scaleBand().domain(this.weatherData.map(d => d.record_date)).range([0, width]).padding(0.2);const y = d3.scaleLinear().domain([0, d3.max(this.weatherData, d => d.temperature)]).range([height, 0]);// 添加柱狀svg.selectAll("rect").data(this.weatherData).join("rect").attr("x", d => x(d.record_date)).attr("y", d => y(d.temperature)).attr("width", x.bandwidth()).attr("height", d => height - y(d.temperature)).attr("fill", "#4CAF50");// 添加坐標軸svg.append("g").attr("transform", `translate(0,${height})`).call(d3.axisBottom(x).tickValues(x.domain().filter((d,i) => !(i%5))));svg.append("g").call(d3.axisLeft(y));// 添加標簽svg.append("text").attr("transform", `translate(${width/2}, ${height + 40})`).style("text-anchor", "middle").text("日期");svg.append("text").attr("transform", "rotate(-90)").attr("y", 0 - margin.left).attr("x",0 - (height / 2)).attr("dy", "1em").style("text-anchor", "middle").text("溫度(℃)");},// 繪制折線圖drawLineChart() {const margin = { top: 30, right: 30, bottom: 50, left: 60 };const width = 800 - margin.left - margin.right;const height = 400 - margin.top - margin.bottom;const svg = d3.select(this.$refs.lineChart).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', `translate(${margin.left},${margin.top})`);// 創建比例尺const x = d3.scaleBand().domain(this.weatherData.map(d => d.record_date)).range([0, width]);const y = d3.scaleLinear().domain([d3.min(this.weatherData, d => d.temperature) - 2, d3.max(this.weatherData, d => d.temperature) + 2]).range([height, 0]);// 創建折線生成器const line = d3.line().x(d => x(d.record_date) + x.bandwidth()/2).y(d => y(d.temperature));// 繪制折線svg.append("path").datum(this.weatherData).attr("fill", "none").attr("stroke", "#2196F3").attr("stroke-width", 2).attr("d", line);// 添加坐標軸svg.append("g").attr("transform", `translate(0,${height})`).call(d3.axisBottom(x).tickValues(x.domain().filter((d,i) => !(i%5))));svg.append("g").call(d3.axisLeft(y));},// 繪制餅圖drawPieChart() {const width = 400;const height = 400;const radius = Math.min(width, height) / 2;const svg = d3.select(this.$refs.pieChart).append('svg').attr('width', width).attr('height', height).append('g').attr('transform', `translate(${width/2},${height/2})`);// 統計天氣狀況const data = Array.from(d3.rollup(this.weatherData,v => v.length,d => d.weather_condition),([name, value]) => ({name, value}));// 創建顏色比例尺const color = d3.scaleOrdinal().domain(data.map(d => d.name)).range(d3.schemeCategory10);// 餅圖生成器const pie = d3.pie().value(d => d.value);// 弧形生成器const arc = d3.arc().innerRadius(0).outerRadius(radius);// 繪制扇形const arcs = svg.selectAll("arc").data(pie(data)).enter().append("g").attr("class", "arc");arcs.append("path").attr("d", arc).attr("fill", d => color(d.data.name)).attr("stroke", "white").style("stroke-width", "2px");// 添加標簽arcs.append("text").attr("transform", d => `translate(${arc.centroid(d)})`).attr("text-anchor", "middle").text(d => d.data.name);}}
};
</script><style>
.charts-container {display: grid;grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));gap: 2rem;padding: 2rem;
}.chart-box {background: white;padding: 1rem;border-radius: 8px;box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}.chart-box h3 {margin: 0 0 1rem;color: #333;
}.chart {width: 100%;height: 400px;
}
</style>
step102:c++ 模擬數據
C:\Users\wangrusheng\source\repos\CMakeProject1\CMakeProject1\CMakeProject1.cpp
#include <iostream>
#include <random>
#include <vector>
#include <string>
#include <iomanip>
#include <cmath>struct WeatherData {int day;double temperature;int humidity;double precipitation;double wind_speed;std::string condition;
};// 生成溫度(可指定范圍)
double generate_temperature(std::mt19937& gen, double min_temp = 10.0, double max_temp = 20.0) {std::uniform_real_distribution<double> dist(min_temp, max_temp);return std::round(dist(gen) * 10) / 10.0; // 保留1位小數
}// 生成濕度(正態分布)
int generate_humidity(std::mt19937& gen) {std::normal_distribution<double> dist(60.0, 15.0);double humidity = dist(gen);humidity = std::clamp(humidity, 0.0, 100.0);return static_cast<int>(std::round(humidity));
}// 生成降水量(20%概率下雨)
double generate_precipitation(std::mt19937& gen) {std::bernoulli_distribution rain_dist(0.2);if (rain_dist(gen)) {std::exponential_distribution<double> amount_dist(1.0 / 5.0); // 平均5mmdouble amount = amount_dist(gen);amount = std::clamp(amount, 0.1, 30.0);return std::round(amount * 10) / 10.0; // 保留1位小數}return 0.0;
}// 生成風速(伽馬分布)
double generate_wind_speed(std::mt19937& gen) {std::gamma_distribution<double> dist(2.0, 2.0);double speed = dist(gen);speed = std::clamp(speed, 0.0, 20.0);return std::round(speed * 10) / 10.0; // 保留1位小數
}// 生成天氣狀況
std::string get_condition(double temp, double precip, int humidity) {if (precip > 0) {return (temp < 3.0) ? "Snow" : "Rain";}if (humidity >= 70) return "Cloudy";if (humidity <= 30) return "Sunny";// 隨機選擇部分多云或陰天static std::vector<std::string> options = { "Partly Cloudy", "Mostly Cloudy" };std::uniform_int_distribution<int> dist(0, 1);std::mt19937 temp_gen(std::random_device{}());return options[dist(temp_gen)];
}// 生成完整月份數據
std::vector<WeatherData> generate_april_data(std::mt19937& gen) {std::vector<WeatherData> data;for (int day = 1; day <= 30; ++day) {WeatherData wd;wd.day = day;wd.temperature = generate_temperature(gen);wd.humidity = generate_humidity(gen);wd.precipitation = generate_precipitation(gen);wd.wind_speed = generate_wind_speed(gen);wd.condition = get_condition(wd.temperature, wd.precipitation, wd.humidity);data.push_back(wd);}return data;
}int main() {// 初始化隨機數生成器std::random_device rd;std::mt19937 gen(rd());// 生成數據auto weather_data = generate_april_data(gen);// 輸出CSV格式std::cout << "Day,Temperature,Humidity,Precipitation,Wind Speed,Condition\n";for (const auto& wd : weather_data) {std::cout << wd.day << ","<< std::fixed << std::setprecision(1) << wd.temperature << "°C,"<< wd.humidity << "%,"<< wd.precipitation << "mm,"<< wd.wind_speed << "m/s,"<< wd.condition << "\n";}return 0;
}
end