質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.00%

requestをimportして動作するプログラムが動かない(仮想環境下)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 985

kawabegolira

score 11

初めましてpython初心者のgoliraです。
今、pythonの仮想環境vent上でrequestを下記プログラムで動かそうとしたのですが
プログラム自体は立ち上がるのですが、"天気"と打っても反応が無く、他のif文である
"干支"、"選ぶ"等のキーワードにも何故か反応しなくなりました。
どうすれば正常に動作するのか、ご教授お願いします。

1:プログラムコード

from import_eto import eto_command
from my_random import choice_command, dice_command
from import_hiduke import(kyou_command, ima_command,
youbi_command)
from forecast import weather_command

def len_command(command):
_    cmd, text = command.split()
_    length = len(text)
_    response = "文字列の長さは{}です".format(length)
_    return response

def heisei_command(command):
_    heisei, year_str = command.split()
_    if year_str.isdigit():
_        year = int(year_str)

_        if year >= 1989:
_            heisei_year = year - 1988
_            response = "西暦{}年は、平成{}年です".format(year, heisei_year)
_        else:
_            response = "西暦{}年は、平成ではありません".format(year)

_    else:
_        response = "数値を指定して下さい"
_    return response

aisatu_file = open("aisatu.txt", encoding="utf-8")
raw_data = aisatu_file.read()
aisatu_file.close
lines = raw_data.splitlines()

bot_dict = {}
for line in lines:
_    word_list = line.split(",")
_    key = word_list[0]
_    response = word_list[1]
_    bot_dict[key] = response

while True:
_    command = input("なんか言え ")
_    response = ""
_    try:
_        for key in bot_dict:
_            if key in command:
_                response = bot_dict[key]
_                break

_        if "平成" in command:
_            response = heisei_command(command)

_        if "長さ" in command:
_            response = len_command(command)

_        if "干支" in command:
_            response = eto_command(command)

_        if "選ぶ" in command:
_            response = choice_command(command)

_        if "サイコロ" in command:
_            response = dice_command(command)

_        if "今日" in command:
_            response = kyou_command()

_        if "現在" in command:
_            response = ima_command()

_        if "曜日" in command:
_            response = youbi_command(command)

_        if "天気" in command:
_            response = weather_command()
_        if not response:
_            response = "日本語喋れや豚野郎"

_            print(response)

_        if "さようなら" in command:
_            print("二度と開くなよまじで")
_            break

except Exception as e:
print("予期せぬエラーが発生しました")
print("種類:", type(e))
print("内容:", e)

”import_eto.py”のコード

coding:utf-8

def eto_command(command):
_    eto, year = command.split()
_    eto_list = ("子", "丑", "寅", "卯", "辰", "巳", "午",
_     "未", "申", "酉", "戌", "亥")
_    eto_number = (int(year) + 8) % 12
_    eto_name = eto_list[eto_number]

_    response = "{}年生まれの干支は「{}」です".format(year, eto_name)
_    return response

"my_random.py"のコード

import random

def choice_command(command):
_    data = command.split()
_    choiced = random.choice(data[1:])
_    response = "「{}」が選ばれました".format(choiced)
_    return response

def dice_command(command):
_    num = random.randrange(1, 100)
_    response = "「{}」の目が出ました".format(num)
_    return response

"import_hiduke.py"のコード

rom datetime import date, datetime

def kyou_command():
_    today = date.today()
_    response = "今日の日付は{}です".format(today)
_    return response

def ima_command():
_    now = datetime.now()
_    response = "現在日時は{}です".format(now)
_    return response

def youbi_command(command):
_    try:
_        data = command.split()
_        year = int(data[1])
_        month = int(data[2])
_        day = int(data[3])
_        one_day = date(year, month, day)

_        weekday_str = "月火水木金土日"
_        weekday = weekday_str[one_day.weekday()]

_        response = "{}は、{}曜日です".format(one_day, weekday)

_    except IndexError:
_        response = "3つの値(年月日)を空白で区切って入力して下さい"
_    except ValueError:
_        response = "正しい日付を入力して下さい"

_    return response

"forecast.py"のコード

import requests

def weather_command():
_    base_url = "http://weather.livedoor.com/forecast/webservice/json/v1"
_    city_code = "230010"
_    url = "{}?city={}".format(base_url, city_code)
_    r = requests.get(url)
_    weather_data = r.json()
_    city = weather_data["location"]["city"]
_    label = weather_data["forecasts"][0]["dateLabel"]
_    telop = weather_data["forecasts"][0]["telop"]

_    response = "{}の{}の天気は「{}」です".format(city, label, telop)
_    return response

2:エラーコード

なんか言え 干支
予期せぬエラーが発生しました
種類: <class 'ValueError'>
内容: not enough values to unpack (expected 2, got 1)
なんか言え 選ぶ
予期せぬエラーが発生しました
種類: <class 'IndexError'>
内容: Cannot choose from an empty sequence
なんか言え 天気
なんか言え 天気
なんか言え 天気

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yoorwm

    2018/03/09 16:24

    「初めまして」なのに「いつも迅速な回答」なのですか?

    キャンセル

  • kawabegolira

    2018/03/09 16:27

    初めて見て頂く人も居るかと、思いまして、すいません、、、

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2018/03/09 17:02

    コードブロックの前後を```で囲んでください。もしくは、コード部分をマウスで選択して上側のタブ</>でも同じことができます。

    キャンセル

回答 1

checkベストアンサー

+3

とりあえずエラーの原因だけ指摘します。

なんか言え 干支
予期せぬエラーが発生しました
種類: <class 'ValueError'>
内容: not enough values to unpack (expected 2, got 1)

import_eto.eto_command を見る限り、西暦も併せて入力すべきです。

なんか言え 選ぶ
予期せぬエラーが発生しました
種類: <class 'IndexError'>
内容: Cannot choose from an empty sequence

やはり my_random.choice_command を見る限り、選択肢を渡すべきです。


基本的には書いたとおりにしか動いていないので、関数の呼び出し方にご留意ください。
また、例外の安易な握り潰しは絶対にしないようにしてください。

Wandboxにコードを起こして再現させたので、一応共有しておきます。Wandbox

コードブロックの適用の仕方

次のようにコードブロックを利用出来ます。

def main():
    print('Hello World!')

if __name__ == __main__:
    main()

方法は二つあります。

  1. コードをハイライトした状態で<code>ボタンを押す
  2. マークダウンを手動で入力する Qiita - Markdown記法 チートシート - コードの挿入

書いてみた

部分的ですが、参考までに。

main.py

from command import eto_command, choice_command

command_dict = {
    '干支': eto_command,
    '選ぶ': choice_command,
}

def interpret_command(input_str):
    command, *args = input_str.split()

    if command in command_dict:
        return command_dict[command](*args)

    return f'「{command}」の意味がわかりません。'


def main():
    while True:
        input_str = input('なんか入力してね: ')
        if not input_str:
            continue

        if 'さようなら' == input_str:
            print('了解。システムを終了します。')
            break

        print(
            interpret_command(input_str), end='\n\n'
        )


if __name__ == '__main__':
    main()

command.py

import random


def eto_command(*year_strs):
    if len(year_strs) != 1:
        return 'コマンドと一緒に西暦を一つだけ入力してね。'

    year_str = year_strs[0]
    try:
        year = int(year_str)
    except ValueError:
        return f'{year_str}は西暦だと解釈できないよ。'

    eto = [
        "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"
    ][(year + 8) % 12]

    return f'{year}年生まれの干支は「{eto}」です。'


def choice_command(*candidate_list):
    if not candidate_list:
        return 'そもそも選択肢がないよ。'

    choiced = random.choice(candidate_list)
    return f'「{choiced}」が選ばれました。'

実行例 おまけ:Wandbox

なんか入力してね: 干支
コマンドと一緒に西暦を一つだけ入力してね。

なんか入力してね: 干支 2018
2018年生まれの干支は「戌」です。

なんか入力してね: 干支 2018 2019
コマンドと一緒に西暦を一つだけ入力してね。

なんか入力してね: 干支 3.14
3.14は西暦だと解釈できないよ。

なんか入力してね: 選ぶ
そもそも選択肢がないよ。

なんか入力してね: 選ぶ 1 2 3
「1」が選ばれました。

なんか入力してね: 選ぶ 1 2 3
「1」が選ばれました。

なんか入力してね: 選ぶ 1 2 3
「2」が選ばれました。

なんか入力してね: 面白いこと言って
「面白いこと言って」の意味がわかりません。

なんか入力してね:
なんか入力してね: さようなら
了解。システムを終了します。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/09 20:01

    ありがとうございます!
    試してみます!

    キャンセル

  • 2018/03/09 20:14

    動きました!
    本当にありがとうごさいます!

    キャンセル

  • 2018/03/09 21:35

    解決されたようで何よりです。

    今回のコードが失敗した原因は主に次の二つですね。
    1. 関数の正しい用法を把握できていなかったこと。
    2. エラーを適切にハンドリング出来ず、情報が潰れてしまっていたこと。

    例外を安易に使うと一気にデバッグが難しくなります。
    tryは、ここぞという場面以外では使わない方が良いでしょう。もちろん、その『ここぞ』を判断するためには幾度とない失敗が必要ではあるのですが。

    ただし except Exception はほぼ全ての例外を捕捉してしまうので厳禁です。

    ---
    コードブロックの適用も出来るようにしておいてくださいね。

    キャンセル

  • 2018/03/23 19:54

    エラーの把握をするためにも、try、exceptの使い方には気を付けたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる