python預(yù)測數(shù)量及QT混合編程--Apple的學(xué)習(xí)筆記

一妇多,前言:

在我上一篇blog QChart任務(wù)數(shù)預(yù)測項目實戰(zhàn)--Apple的學(xué)習(xí)筆記 中有一個python預(yù)測任務(wù),今天完成了并且進行QT c++及python混合編程后的集成写半。

二吏恭,功能:

要進行預(yù)測每天會新學(xué)習(xí)多少項內(nèi)容惠豺。然后繼續(xù)按艾賓浩斯曲線來處理。

三徒仓,思路分析:

哪些先分析下數(shù)據(jù)有什么特征腐碱,就會發(fā)現(xiàn)每天學(xué)習(xí)數(shù)量幾乎都少于10項。然后周末或周一新學(xué)習(xí)的數(shù)量會筆記多掉弛。周五新學(xué)習(xí)的數(shù)量會比較少症见。這是我的個人規(guī)律,周末不上班殃饿,所以學(xué)習(xí)數(shù)量可以多些谋作,周五一般就想休息了。

四乎芳,數(shù)學(xué)建模:

這個不屬于線性回歸遵蚜,屬于數(shù)據(jù)分類問題。那么預(yù)測每天會新學(xué)習(xí)多少項內(nèi)容的數(shù)學(xué)模型就簡化為如下:
預(yù)測周一的學(xué)習(xí)數(shù)量奈惑,周二的學(xué)習(xí)數(shù)量一直到周日的學(xué)習(xí)數(shù)量吭净,而且數(shù)組范圍為【1,10】。
機器學(xué)習(xí)里面首先想到樸素貝葉斯肴甸,由于此模型都沒有什么條件概率寂殉。所以又簡化為了計算周一出現(xiàn)[0,10]中哪個概率最大,則預(yù)測出將來的周一新學(xué)習(xí)項的數(shù)量原在。同理去推導(dǎo)周二到周日新學(xué)習(xí)的數(shù)量友扰。

python算法模擬實驗

mylist1=[[5,1,4,1,0,5],  #周一
         [1,2,1,3,3,4]]  #周二
useValue=[0,0]

def forecast():
    for date in range(2):
        maxNum = 0
        for i in range(10,-1,-1):  # 10 to 0 開始遍歷
            if (mylist1[date].count(i))>maxNum:   #select the first max value,if counter is the same,select the max one
                maxNum = mylist1[date].count(i)
                useValue[date] =i
    print (useValue)
    
if __name__ == '__main__':
    forecast()

輸出結(jié)果
[5, 3]
代表周一預(yù)測新學(xué)習(xí)數(shù)量加5,周二加3庶柿。

五村怪,總結(jié)

由于我是2019-10-01開始使用這套系統(tǒng)的,所以當(dāng)前的訓(xùn)練數(shù)據(jù)就比較少浮庐,不準(zhǔn)確实愚。我的概率在某個星期n計算會發(fā)現(xiàn)都是一樣的,在這樣的情況下使用的是最大值就不太準(zhǔn)兔辅。

六,遇到的問題記錄

1.解決了python37_d無法打開的問題击喂,自己再copy一個然后重命名為_d.lib即可维苔。
2.Py_IsInitialized報錯,需要按網(wǎng)上說的修改python的include中的一個頭文件懂昂。
3.添加python模塊lib的方法可以右擊工程添加介时,也可以手工添加,最后用的是手工在pro文件中添加。

七沸柔,學(xué)到的技術(shù)總結(jié)

  1. QT c++和python的混合編程技能循衰。
  2. 復(fù)習(xí)了機器學(xué)習(xí)中的樸素貝葉斯。
  3. QT Vector的copy用<<即可褐澎。
  4. 掌握了datetime的各種轉(zhuǎn)換会钝。
  5. 學(xué)習(xí)了python collections進行歸類的字典輸出。

八工三,github源碼上傳

https://github.com/AppleCai/taskForecast

九迁酸,運行效果圖

結(jié)果.png

十,python源碼

import sqlite3
from datetime import datetime
from collections import Counter

mydatelist=[
         [],  #周日
         [],  #周一
         [],  #周二
         [],  #周三
         [],  #周四
         [],  #周五
         [],  #周六
         ]
useValue=[0,0,0,0,0,0,0] # 周日俭正,周一~周六每天新學(xué)的任務(wù)數(shù)

def connectUserDb():
    con = sqlite3.connect(r'D:\Djangoproj\myWebTest\db.sqlite3')
    return con

def queryUserRecords(con):
    mytemplist = []
    # 因為我的django工程師10月初做的奸鬓,所以從2019年10月1日后的數(shù)據(jù)算是有效的。然后開始統(tǒng)計
    cursor = con.execute("SELECT modify_date FROM myfile_basicinfo WHERE  modify_date>='2019-10-01'")
    # 僅提取日期字符串掸读,不需要時間
    for item in cursor:
        mytemplist.append(item[0][0:10])
    # 對每一相同日期歸類串远,以字典顯示{日期:出現(xiàn)次數(shù)}
    res = Counter(mytemplist)
    print(res)
    for key in res:
        # 先將str轉(zhuǎn)成datatime格式后再轉(zhuǎn)為周幾
        anyday = datetime.strptime(key, '%Y-%m-%d').strftime("%w") # key為日期字符串,做處理
        tempnum = res[key]
        # 預(yù)測的每天新增學(xué)習(xí)數(shù)量(即出現(xiàn)次數(shù))不超過10項儿惫,超過10則用10代表
        if (tempnum>10):
            tempnum = 10
        mydatelist[int(anyday)].append(tempnum)  # 將日期轉(zhuǎn)為周幾澡罚,并將出現(xiàn)次數(shù)copy到數(shù)組。

def forecast():
    for date in range(7):  # date 0 to 6
        maxNum = 0
        for i in range(10,-1,-1):  # i is from 10 to 0
            if (mydatelist[date].count(i))>maxNum:   # 若出現(xiàn)次數(shù)相同姥闪,則選擇字?jǐn)?shù)最大的值作為預(yù)測性學(xué)習(xí)數(shù)量
                maxNum = mydatelist[date].count(i)
                useValue[date] =i
    print (useValue)

def maintask():
    connect=connectUserDb()    # 連接數(shù)據(jù)庫
    queryUserRecords(connect)  # 查詢曾經(jīng)學(xué)習(xí)的記錄始苇,并且處理數(shù)據(jù)獲得每天(周一~周日)新學(xué)習(xí)的數(shù)量
    forecast()                 # 進行機器分類學(xué)習(xí),在0-10之前出現(xiàn)最大的概率
    return useValue

if __name__ == '__main__':
    maintask()

十一筐喳,QT widget部分源碼

#include "widget.h"
#include "ui_widget.h"



Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{

    pythonCode();
    ui->setupUi(this);
    //QDateTime curDateTime=QDateTime::currentDateTime();
    curDate=QDate::currentDate();
    lastDate = curDate.addDays(15);
    ui->txtDate->setText(curDate.toString("yyyy-MM-dd"));
    ui->cb_rangeselect->addItem("one week");
    ui->cb_rangeselect->addItem("two week");
    connectSQL();
    addmyForecast();
}

void Widget::pythonCode()
{
    Py_Initialize();
    //如果初始化失敗催式,返回
    if(!Py_IsInitialized())
    {
        qDebug()<<"Initlize error";
    }
    else
    {
        qDebug() << "inititalize success";
    }
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");  //即exe運行目錄下放入python文件
    PyObject* pModule =PyImport_ImportModule("forecast");
    if(!pModule)
    {
        qDebug()<<"can not open python file";
    }
    else
    {
        qDebug() << "Import success";
    }

    // 加載函數(shù)maintask()
    PyObject *pLoadFunc = PyObject_GetAttrString(pModule, "maintask");

    if (!pLoadFunc) {
        printf("get func failed!");
    }
    else {
        qDebug() << "get func success";
    }
    PyObject *retObjectX = PyObject_CallObject(pLoadFunc, nullptr); // 獲得python腳本返回數(shù)據(jù)

    if (retObjectX == nullptr) {
        qDebug() << "no return value";
        return ;
    }

    int row = PyList_Size(retObjectX);
    for (int i = 0; i < row; ++i) {
        PyObject *singleItem = PyList_GetItem(retObjectX, i);
        int res = 0;
        PyArg_Parse(singleItem,"i",&res);//轉(zhuǎn)換返回類型
        ForecastVect.push_back(res);
        //double item = PyFloat_AsDouble(singleItem);
        //tmpVect.push_back(item);
    }
    qDebug()<<"test start";
    qDebug()<<ForecastVect;
    qDebug()<<"test end";
    Py_Finalize();
}
Widget::~Widget()
{
    delete ui;
}
void Widget::ShowBar()
{
    QBarSet *set0 = new QBarSet("taskNum");

    QStringList categories;
    int i;
    for(i=0;i<showdays;i++)
    {
        *set0<< CalCnt[i];
        categories<<curDate.addDays(i).toString("MMdd");
    }

    QBarSeries *series = new QBarSeries();
    series->append(set0);

    series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 設(shè)置數(shù)據(jù)系列標(biāo)簽的位置于數(shù)據(jù)柱內(nèi)測上方
    series->setLabelsVisible(true); // 設(shè)置顯示數(shù)據(jù)系列標(biāo)簽

    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("forecast task number");
    chart->setAnimationOptions(QChart::SeriesAnimations);

    QBarCategoryAxis *axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QValueAxis *axisY = new QValueAxis();
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    ui->widgetBar->setChart(chart);
}

void Widget::connectSQL()
{
   QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("D:\\Djangoproj\\myWebTest\\db.sqlite3");
    if (!db.open())
    {
        qDebug() << "open error";
    }
    else
    {
         qDebug()<<"ok";
    }
    SQLhandler();
    db.close();
}

void Widget::SQLhandler()
{
    QSqlQuery sql_query;
    //qDebug()<<QString("select phase,review_date from myfile_reviewInfo where phase<8 and review_date<'%1'").arg(lastDate.toString("yyyy-MM-dd"));
    QString select_sql = QString("select phase,review_date from myfile_reviewInfo where phase<8 and review_date<'%1'").arg(lastDate.toString("yyyy-MM-dd"));
    sql_query.prepare(select_sql);
    if(!sql_query.exec())
    {
        qDebug()<<sql_query.lastError();
    }
    else
    {
        while(sql_query.next())
        {
            ReviewPhase.append(sql_query.value("phase").toInt());
            DateInfo.append(sql_query.value("review_date").toString());
        }
    }
    // copy向量
    ReviewPhasePrevCopy<<ReviewPhase;
    DateInfoPrevCopy<<DateInfo;
  }

void Widget::addmyForecast()
{
    //QString  curDay = curDate.toString("ddd");
    QMap<QString, int> week;
    week.insert("周日",0);
    week.insert("周一",1);
    week.insert("周二",2);
    week.insert("周三",3);
    week.insert("周四",4);
    week.insert("周五",5);
    week.insert("周六",6);
    //qDebug()<<week[curDay];  //周幾轉(zhuǎn)為數(shù)字下標(biāo),從而可以從ForecastVect讀取預(yù)測新學(xué)任務(wù)數(shù)

    int cnt=0;
    int i;
    for (i=1;i<14;i++)  // 當(dāng)天新增的不進行預(yù)測避归,對2周內(nèi)的后13天進行新增預(yù)測
    {
        QDate nextDate = curDate.addDays(i);
        QString tempstr=QString("%1 %2").arg(nextDate.toString("yyyy-MM-dd")).arg("20:00:00");
        cnt=ForecastVect[week[nextDate.toString("ddd")]];
        // 將新增預(yù)測項數(shù)量添加到數(shù)據(jù)庫中
        DateInfo.insert(DateInfo.begin(),cnt,tempstr);
        ReviewPhase.insert(ReviewPhase.begin(),cnt,0);
    }
    qDebug()<<DateInfo;

}

void Widget::on_ck_ONOFF_clicked(bool checked)
{
    QFont font=ui->ck_ONOFF->font();
    font.setBold(checked);
    ui->ck_ONOFF->setFont(font);
    ui->pushButton->setEnabled(true);
    bl_addML = checked;
    qDebug()<<bl_addML;
}

void Widget::on_pushButton_clicked()
{
    ui->pushButton->setEnabled(false);
    // 根據(jù)checkbox來選擇帶新增預(yù)測的數(shù)據(jù)或不帶新增預(yù)測的數(shù)據(jù)
    if (bl_addML)
    {
        CalculateTaskNum(ReviewPhase,DateInfo);
    }
    else
    {
        CalculateTaskNum(ReviewPhasePrevCopy,DateInfoPrevCopy);
    }
    ShowBar();
}

void Widget::CalculateTaskNum(const QVector<int> &vReviewPhase,const QVector<QString> &vDateInfo)
{
    int i;
    CalCnt.clear();
    for(i=0;i<14;i++)
    {
        CalCnt.append(0);
    }
    int index=0;
    for(auto iphase:vReviewPhase)
    {
        int diff = 0;
        int j=0;
        /* change Datetime string to Data */
        QDate tempDate = QDateTime::fromString(vDateInfo[index], "yyyy-MM-dd hh:mm:ss").date();

        diff = curDate.daysTo(tempDate);
        if(diff>=0 && diff<14)
        {
            /* add the default review date */
            CalCnt[diff]++;
            j=iphase+1;  /* TBD */
            /* accumulation for each phase while diff<15 */
            while(diff<14 && j<6)
            {

                    diff=diff+myRule[j++];
                    if(diff>=0 && diff<14)
                    {
                        CalCnt[diff]++;
                    }
            }
        }
        else
        {
            j=iphase++;
            /* some item didn't review on time, so is minus value */
            while(diff<14 && diff>=0 && j<6)
            {
                    diff=diff+myRule[j++];

                    if(diff>0 && diff<14)
                    {
                        CalCnt[diff]++;
                    }
            }
        }

        /* next item */
        index++;
    }
}

void Widget::on_cb_rangeselect_currentIndexChanged(const QString &arg1)
{
    //Q_UNUSED(arg1)
    if(arg1=="one week")
    {
        showdays = 7;
    }
    else
    {
        showdays = 14;
    }
    ui->pushButton->setEnabled(true);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荣月,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子梳毙,更是在濱河造成了極大的恐慌哺窄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件账锹,死亡現(xiàn)場離奇詭異萌业,居然都是意外死亡,警方通過查閱死者的電腦和手機奸柬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門生年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廓奕,你說我怎么就攤上這事抱婉〉凳澹” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵蒸绩,是天一觀的道長衙四。 經(jīng)常有香客問我,道長患亿,這世上最難降的妖魔是什么传蹈? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮窍育,結(jié)果婚禮上卡睦,老公的妹妹穿的比我還像新娘。我一直安慰自己漱抓,他們只是感情好表锻,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乞娄,像睡著了一般瞬逊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仪或,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天确镊,我揣著相機與錄音,去河邊找鬼范删。 笑死蕾域,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的到旦。 我是一名探鬼主播旨巷,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼添忘!你這毒婦竟也來了采呐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤搁骑,失蹤者是張志新(化名)和其女友劉穎斧吐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仲器,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡煤率,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乏冀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝶糯。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖煤辨,靈堂內(nèi)的尸體忽然破棺而出裳涛,到底是詐尸還是另有隱情,我是刑警寧澤众辨,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布端三,位于F島的核電站,受9級特大地震影響鹃彻,放射性物質(zhì)發(fā)生泄漏郊闯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一蛛株、第九天 我趴在偏房一處隱蔽的房頂上張望团赁。 院中可真熱鬧,春花似錦谨履、人聲如沸欢摄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怀挠。三九已至,卻和暖如春害捕,著一層夾襖步出監(jiān)牢的瞬間绿淋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工尝盼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吞滞,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓盾沫,卻偏偏與公主長得像裁赠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子疮跑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容