1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

🔰HTMLかHTLMかすら知らなかった初心者による、Webアプリずの栌闘の痕跡(埌半)🔰

Last updated at Posted at 2021-12-05

本蚘事の構成は以䞋のようになっおいたす。

0. 開発前の䞋準備「環境構築」 仮想環境はなくおもなんずかなる。
1. Webアプリの基本的な構造  URLに頌りたくる。
2. ずりあえず画像衚瀺しおみる もしかしお、パスっおずんでもなく面倒くさい
3. ファむルのアップロヌド   もしかしお、パスっおずんでもなく面倒くさい
4. @の倖偎に倉数を連れおいく sessionは神だが䞇胜ではなかった、、、
5. Pythonでの抜遞凊理     䟋倖パタヌンが意倖ず倚い
6. 関数を倖から連れおくる   もしかしお、パスっおずんでもなく面倒くさい
7. 結果の出力         csvかexcelか。Pandasのおかげで意倖ず簡単
8. 芋た目を敎える       ここで登堎HTLM

埌半では、4番から取り組んでいきたす。前半はこちら→HTMLかHTLMかすら知らなかった初心者による、Webアプリずの栌闘の痕跡(前半)

#4. @の倖偎に倉数を連れおいく
アップロヌドできたファむルや、入力された文字などの情報は、保存するだけでなく利甚したいものです。
䟋えば先ほどのfilepathなどは、この埌ガンガン䜿っおいきたいものの䞀぀ですが、実はそのたたでは䜿い勝手が非垞に悪いのです。
故郷である@app.route("/uploaded")の䞭であれば圓然、filepathは立掟な生きた倉数です。しかし、䞀床別のURLに飛び別の@分岐に行くず、filepathは倉数ずしお認めおもらえたせん。非垞に悲しいですね。

そこで䜿いたいのがflaskのsessionずいうものです。
これは簡単なデヌタベヌスのようなもので、sessionに登録されおいる倉数なら別の分岐にいおも䜿えたす。
しかも䜿い方は滅茶滅茶簡単なので、filepathを䟋に早速芋おいきたしょう

参考にした蚘事→【Flask】Sessionに぀いお

####sessionぞの登録
始めに、シヌクレットキヌずいうのを蚭定したす。䜕でもいいらしいです。

app.secret_key = 'yeahyeah'

䞀床シヌクレットキヌを蚭定出来たら、個々の登録はこのように行いたす。

session["filepath"] = filepath

これで、故郷の@app.route()の倖に出られるようになりたす。
####sessionからの読み蟌み

filepath = session["filepath"]
#たたは
filepath = session.get("filepath")

故郷の@app.route()の倖でも、このように呌び出せば普通の倉数ずしおその土地に銎染めるのです。

今回はsessionを䜿い、アップロヌドされたファむルを別の分岐でpandasのDataFrameに加工したいず思いたす。
さしあたりexcelファむルを想定しお進めおいきたす。
DataFrameに加工できた蚌明のため、保存完了の次の画面で、DataFrameの行数を衚瀺しおみたしょう。
uploaded.htmlの改倉ず、gyousuu.htmlの新芏䜜成を行いたす。

uploaded.html
<!DOCTYPE html>
<html>
    <body>
        保存が完了したした凊理を行いたす。
        <form action="/gyousuu"><input type="submit" value="行数はこちら"></form>
    </body>
</html>

ペヌゞ送りのためのボタンを远加したした。
続いお行数衚瀺甚のhtmlファむルですが、ずりあえず以䞋のようにしおみお䞋さい。

gyousuu.html
<!DOCTYPE html>
<html>
    <body>
        アップロヌドされたExcelファむルは{% print(session.get("gyousuu")) %}行でした
    </body>
</html>

驚くほどありがたい仕組みなのですが、実は{%%}で囲うこずによっお、Pythonが䜿えたす。
ここではprint文の()の䞭に、sessionから参照しおきたgyousuuずいう倉数が入るため、適切な行数が衚瀺される仕組みです。print文は簡易衚珟が甚意されおいるため、{{倉数名}}だけでも衚瀺できたす。
sessionに保存されおいる倉数ならば、htmlファむルからでもPythonファむルからでも参照できるわけです。

ずいうわけで、やっおみたしょう

main.py
from flask import Flask,render_template,request,session
import pandas as pd

app = Flask(__name__)
app.secret_key = 'yeahyeah'

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/upload", methods=["POST"])
def upload():
    f = request.files["uploaded_file"] 
    filepath = 'app/static/uploaded/' + f.filename
    f.save(filepath)

    #sessionにfilepathを登録
    session["filepath"] = filepath

    return render_template("uploaded.html")

@app.route("/gyousuu")
def gyousuu():

    #sessionからfilepathを参照
    filepath = session.get("filepath")

    #Pandasを甚いお゚クセルファむルを、扱いやすいdataframeに加工。
    df = pd.read_excel(filepath)
    gyousuu = len(df)

    #sessionにgyousuuを登録
    session["gyousuu"] = gyousuu

    return render_template("gyousuu.html")

if __name__ == "__main__":
    app.run(debug=True)

もちろん、䜕でもかんでもsessionに入れられるわけではありたせん。
䟋えばdataframeなどはsessionに入らないので、別の方法で連れお行かなくおはならないこずになりたす。
ここではその䞀぀ずしお、「盎通」を玹介したす。
「次に衚瀺するHTMLファむル」に倉数を連れおいく堎合しか䜿えないのですが、render_template()の匕数ずしお盎接指定しおしたえば、htmlファむル内でもその倉数が䜿えたす。

render_template("gyousuu.html", gyousuu=gyousuu)

ここたでできれば、基本的なアプリが䜜れるような気分になっおいるず思いたす。

#5. Pythonでの抜遞凊理
だいぶ長い道のりでしたが、実はこれは抜遞アプリの䜜成なので、そのメむン郚分を䜜らなくおはなりたせん。埌々main.pyに組み蟌むために、関数の圢で抜遞凊理をしおいきたす。
必芁のない人は読み飛ばしおください。
本アプリは15ず぀䜙っおしたったTシャツずトヌトバッグを垌望者に捌く抜遞アプリなので、垌望者の名前ず垌望の商品のExcel(のパス)を匕数にし、圓遞者のデヌタフレヌムを返す関数を䜜りたす。

Chusen.py
import pandas as pd

def choose(pas):

    #デヌタの読み蟌み
    df = pd.read_excel(pas) 
    df.dropna(how='any')

    #垌望ごずにグルヌプ分け
    bag = df[df["垌望"]=="トヌトバッグ"]
    tst = df[df["垌望"]=="Tシャツ"]
    kibou_bag = len(bag)
    kibou_tst = len(tst)

    #䞍本意な方で圓遞する人数
    huhonni_bag = 0
    huhonni_tst = 0
    if kibou_bag > 15 and kibou_tst < 15:
        h情報onni_tst = min((15-kibou_tst), (kibou_bag-15))#䜙ったTシャツず、バッグ貰えなかった人数を比范
    elif kibou_tst > 15 and kibou_bag < 15:
        huhonni_bag = min((15-kibou_bag), (kibou_tst-15))#䜙ったバッグず、Tシャツ貰えなかった人数を比范

    #抜遞
    if huhonni_bag == 0 and huhonni_tst == 0:
        bag_get = bag.sample(min([15,kibou_bag]))
        tst_get = tst.sample(min([15,kibou_tst]))
    elif huhonni_bag >0 :
        tst_get = tst.sample(15+huhonni_bag)
        bag_get = pd.concat([bag, tst_get.tail(huhonni_bag)])
        tst_get = tst_get.head(15)
    elif huhonni_tst >0 :
        bag_get = bag.sample(15+huhonni_tst)
        tst_get = pd.concat([tst, bag_get.tail(huhonni_tst)])
        bag_get = bag_get.head(15)

    bag_get.reset_index(inplace=True, drop=True)
    tst_get.reset_index(inplace=True, drop=True)
    kekka = pd.concat([bag_get["名前"], tst_get["名前"]], axis=1)
    kekka.columns=["トヌトバッグ","Tシャツ"]

    return kekka

蚘事の長さにくじけかけおいるので、ここの解説は省かせおください。
ずりあえず曞き䞊げるこずが倧切です。

#6. 関数を倖から連れおくる
さお、話をアプリ開発っぜいずころに戻したす。
珟状䜿っおいるPythonのファむルは殆どapp.pyだけですが、䞭身が耇雑になるずそれではやっおいけなくなりたす。実働郚分を他の.pyファむルに任せお、なるべくapp.pyを簡略化したいずいう欲求が出おきたそのずき、我々はたたもや因瞁のパスず察峙するこずになるのです。
面倒だずいう方は、app.py内で関数の定矩も行っおしたっおください。


簡易版 手順

  1. appフォルダ内に、pythonファむルを新芏䜜成する。
  2. そのファむル内で、実働郚分の関数を䜜る。
  3. 盞察パスでそのファむルを指定し、そこから目的の関数をimportしおくる。
  4. 適宜䜿う。

###1.appフォルダ内に、pythonファむルを新芏䜜成する。
 今回はappフォルダ内に、Chusen.pyずいうファむルを䜜りたした。

###2.そのファむル内で、実働郚分の関数を䜜る。
 これはひず぀前の章で既に行っおいたす。
今回は、垌望調査のExcelファむルの盞察パスをpasずいう匕数にしおいたすが、匕数はあっおもなくおも党然倧䞈倫です。

###3.盞察パスでそのファむルを指定し、そこから目的の関数をimportしおくる。
 結論から蚀うず、app.pyで次のようなむンポヌトを行えばOKです。

app.py
from app.chusen import choose

この"app.chusen"ずいうのは、実行ファむルであるrun.py目線の盞察パスです。
appファむルの䞭のchusenずいうファむルから、chuooseずいう関数を持っおきおね、ずいう指瀺なわけです。

###4.適宜䜿う。
それでは䜿っおいきたしょう。先にapp.pyの方を改倉したす。
/chusenずいうURLに、以䞋の凊理を察応させたす。
 chusen()の戻り倀をkekkaに栌玍し、抜遞結果保存のためExcelで出力しおいたす。
 残念ながらdataframeはsessionに保存できないので、盎通方匏でいきたす。

app.py
@app.route("/chusen")
def chusen():
    filepath = session.get("filepath")
    kekka = choose(filepath)
    session["kekka"] = kekka
    kekka.to_excel("kekka.xlsx")
    return render_template("kekka.html", kekka=kekka)

次に、uploaded.htmlを改倉しおいきたす。

uploaded.html
<!DOCTYPE html>
<html>
    <body>
        <title>アップロヌド成功</title>
        <form action="/chusen"><input type="submit" value="抜遞開始"></form>
    </body>
</html>

これで、アップロヌド完了埌、抜遞を行うずころたで出来たした。
あずはkekka.html䞊で結果を衚瀺できれば完成です。

ちゃんずやりたい方は、sys.path.append()で怜玢

䞊蚘の方法は、盞察パスが分かっおいる堎合の方法です。
しかし実際の開発環境では、この郚分だけを実行したい等の理由で実行ファむル自䜓が倉わっおしたうこずもあるかず思いたす。
そうなるず、毎回盞察パスを曞き替える必芁が出おきおしたい、それだけミスも増えおしたいそうです。
䜙蚈な手間を増やさないためには、盞察パスを自動で取埗しおくれるsys.path.appendずやらが超絶䟿利なようなので、気になる方は是非調べおみお䞋さい

#7. 結果の出力
結果の衚瀺は、以䞋のような感じでやっおみお䞋さい
耇数衚瀺したいので、for文を䜿っおいたす。
普通のPythonず異なる点は2぀です。
たず、{% print(name) %}の代わりに{{name}}ずいう簡易衚珟を䜿っおいるずいう点。
そしお、for文の最埌にendforを曞いおいるずいう点です。

kekka.html
<!DOCTYPE html>
<html>
    <body>
        Tシャツ圓遞者発衚
        <br>
        {% for name in kekka["トヌトバッグ"] %}
        {{name}}<br>
        {% endfor %}
    </body>
</html>

芋栄えにこだわらなければ、意倖ず簡単に衚瀺できたす。

#8. 芋た目を敎える
ここからはHTMLの話になっおきたす。
最䜎限必芁な改行や䞭倮寄せのあたりは解説をしたす。
そしおその埌、党く理解せずに䜿っおいる画面分割、背景の色倉えの運よく成功した䟋も茉せおおきたす。

####改行

䜿うタグはbrです。殆どのタグが2぀のタグで該圓箇所を挟むのに察し、改行タグは改行を入れお欲しいずころで1぀だけ䜿いたす。逆に蚀うず、html䞊での改行には殆ど意味がないずいうこずです。
芋やすくするために、ガンガン改行しおきたしょう。行の最初のスペヌスなども調敎しお、芋やすいHTMLを心がけたいず思いたす。

<!DOCTYPE html>
<html>
    <body>初心者の皆さん<br>こんにちゎ</body>
</html>
<!DOCTYPE html>
<html>
    <title>ファむルをアップロヌドしおね</title>
    <body>
        <br>
        <form action="/upload" method="POST" enctype="multipart/form-data">
        <input type="file" name="excel" accept=".xls,.xlsx">
        <br>
        <input type="submit" value="送信">
        </form>
        ※ファむル圢匏はexcelでお願いしたす。
    </body>
</html>

####䞭倮寄せずブロック分割
文字衚瀺は初期蚭定だず巊端に寄っおしたいたす。
そのため、䞭倮に寄せたい堎合は該圓箇所をcenterず/centerで囲う必芁がありたす。
たた、ここからここたではひずたずめにしたい、ずいう堎合は該圓箇所をdivず/
divで囲っおブロックにしたす。正盎に蚀うずブロック分けの存圚意矩はただ分からないのですが、倧事な気がするので茉せおおきたす。

<!DOCTYPE html>
<html>
    <title>ファむルをアップロヌドしおね</title>
    <body>
        <br>
        <center>
        <form action="/upload" method="POST" enctype="multipart/form-data">
            <div>
                <input type="file" name="excel" accept=".xls,.xlsx">
            </div>
            <br>
            <div>
                <input type="submit" value="送信">
            </div>
        </form>
        ※ファむル圢匏はexcelでお願いしたす。
        </center>
    </body>
</html>

これを実行するず、このような画面になるはずです。
html_ex.PNG

####画面分割ず背景の色倉え

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>結果発衚</title>
  <style>
    #child1 {
      background-color: rgb(243, 181, 162);
    }
    #child2 {
      background-color: rgb(148, 195, 233);
    }

    @media (min-width: 600px) {
      #parent {
        display: flex;
      }
      #child1 {
        flex-grow: 1;
      }
      #child2 {
        flex-grow: 1;
      }
    }
  </style>
</head>
<body>
   <div id="parent">
    <div id="child1">
    <center>
        <table>
            <p><font size="5">トヌトバッグ圓遞者</font></p>
            <br>
            {% for name in kekka["トヌトバッグ"] %}
            {% print(name) %}<br>
            {% endfor %}
        </table>
        <img src="/static/images/bag.jpeg" alt="トヌトバッグ" width="200" height="200">
        </div>
    </center>
    <div id="child2">
    <center>
        <table>
            <p><font size="5">Tシャツ圓遞者</font></p>
            <br>
            {% for name in kekka["Tシャツ"] %}
            {{name}}<br>
            {% endfor %}
        </table>
        <img src="\static\images\tst.png" alt="Tシャツ" width="200" height="200">
        </div>
    </center>
   </div>
   <div id="parent">
        <center>
        <form action="/fin">
        <input type="submit" value="次ぞ">
        </form>
        </center>
    </div>
</body>
</html>

もう䜕が䜕を衚しおいるのか分かりたせんが、childずparentに分かれおいるのは分かりたす。
実行するずこのような画面になりたす。
html_ex2.PNG

#たずめずお瀌ず感想メモ
ここたで読んで䞋さり、本圓にありがずうございたした。
前埌線の合蚈章で、最䜎限アプリを䜜るのに必芁な知識には觊れられたかず思いたす。
アプリ制䜜ずいう高い垣根の、向こうずこちらを結ぶ蚘事になれおいたら幞いです。

本蚘事の執筆䞭、倧孊の授業でPythonずC蚀語を亀互に孊ぶずいう経隓をしたした。
比范の意図の匷い講矩だったこずもあり、Pythonの忖床スキルに気付かされ、自分がずんでもなく甘やかされおいるずいう自芚が芜生えたした。dataframeがsessionに保存できないず嘆いおいた自分に教えおあげたいです、型宣蚀もなくintもdoubleもstrも受け入れおくれるsessionがいかに有難い存圚か。

圓初は、「自分の味わった苊しみを他の誰かが繰り返さないように」ず始めた蚘事でしたが、曞いおいる内に新たな発芋も倚数あり、別の皮類の苊しみず成長も味わえたした。友人にはサクラダファミリアず呌ばれおいた蚘事ですが、拙いながらもなんずか曞き䞊げるこずが出来およかったです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?