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

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

ただいまの
回答率

88.78%

[python]ドラえもん栗まんじゅう問題

解決済

回答 4

投稿

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

FoiFoi

score 15

やりたいこと

  • dictionaryを関数に入力して、entry_objectの面積合計がtarget_dicの各valueを超えた時にそれぞれのkeyを用いて

"{key}がまんじゅうで一杯になるのに{count}分要します。"

を出力したい。

現状

  • '東京ドームがまんじゅうで一杯になるのに45分要します。'で終了してしまう

    dicの1つ目のvalueを検討し、returnを返しroopが終了してしまう
    (全てのvalueが検討されない)

  • 理想
    '東京ドームがまんじゅうで一杯になるのに45分要します。'
    '地球がまんじゅうで一杯になるのに●分要します。'
    '太陽がまんじゅうで一杯になるのに△分要します。'

コード

def baibai_inn_time_counter_1 (entry_object, target_dic):

    count = 0

    while True:
        for key, value in target_dic.items():
            if entry_object * 2 ** count/5  > value:
                return "{key}がまんじゅうで一杯になるのに{count}分要します。".format(key = key, count = count)
            else:
                count += 5

関数への入力

input_dic = {"東京ドーム":1240000, "地球":1.08269693243E+21, "太陽":1.1494040321933E+46}
baibai_inn_time_counter_1(6.5e-5, input_dic)

出力

'東京ドームがまんじゅうで一杯になるのに45分要します。'

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • t_obara

    2019/04/04 16:51

    formatについてお調べになりましたか?「python format」でググればどのように使うべきかがわかりそうですが。ちなみに、地球が●としたいのに、1.82..を入力としているのは何故ですか?

    キャンセル

  • FoiFoi

    2019/04/04 17:26

    >formatについてお調べになりましたか?
    以下サイトを確認しております。
    https://note.nkmk.me/python-format-zero-hex/

    >地球が●としたいのに、1.82..を入力としているのは何故ですか?
    本問題は、entry_obectの個数が5分おきに倍々されていくというものでして、東京ドーム・地球・太陽のそれぞれがなん分後にentry_obectで満ちてしまうかという問題です。
    そのため1.082..というのは地球の体積です。

    キャンセル

  • t_obara

    2019/04/04 19:21

    数字の意味をお聞きしているのではなく、●と印字したいのですよね?それであれば、●を設定すべきではないのでしょうか?という疑問です。あるいは体積を元に●を印字するようなロジックがあるのでしょうか?

    キャンセル

  • FoiFoi

    2019/04/04 20:35 編集

    >あるいは体積を元に●を印字するようなロジックがあるのでしょうか?

    はい、こちら体積を個数が増幅するentry_obectが満たすには何分かかるかというロジックが関数内if以下にございます。そのため●は体積という入力を受けて時間(分)が出力されます。

    キャンセル

回答 4

checkベストアンサー

+1

提示コードにはいくつか質問点以外にもいくつか問題があります。

まず、entry_object * 2 ** count/5は演算優先順位によりentry_object * 2 ** count / 5と誤動作します。
entry_object * 2 ** (count/5)のように明示的にカッコで優先順位を指定する必要があります。
以下確認コード

for count in range(0,20,5):
    entry_object = 1
    v1 = entry_object * 2 ** count/5  # 誤
    v2 = entry_object * 2 ** (count/5)# 正
    print(count,v1,v2)
"""
0 0.2 1.0
5 6.4 2.0
10 204.8 4.0
15 6553.6 8.0
"""

次に、提示コードは入力要素(面積)が昇順であることを前提としているようですが、仕様上、辞書は要素の並びが不定です。よって(名称,面積)のタプルなりで管理する方がよいです。(cpythonでの実装上は問題ないのですが念のため)

最後にfor と whileのループの関係が根本的におかしいです。
以上を修正したコードが以下になります。
なお、コードの確かさを確認するために、まずは手計算できるような単純かつ小さい数値で動かしてみることをお勧めします。

def baibai_inn_time_counter_1 (entry_object, target_tpl):
    count = 0
    ret = []
    for t in target_tpl:
        while True:
            cur_s = entry_object * 2 ** (count/5)
            print(count,cur_s) # テスト表示

            if cur_s > t[1]:
                ret.append("{name}がまんじゅうで一杯になるのに{count}分要します。".format(name = t[0], count = count))
                count += 5
                break
            count += 5

    return ret

input_dic ={"100㎡?":100, "10㎡?":10, # テストデータ
            "東京ドーム":1240000, "地球":1.08269693243E+21, "太陽":1.1494040321933E+46}
# 確実に個数の昇順になるようにタプルで管理&ソートする
input_tpl = [(k,v) for k,v in input_dic.items()]
input_tpl = sorted(input_tpl,key=lambda x:x[1])
print(input_tpl)

S = 6.5e-5
#S = 1 # まずは単純な数値で確認
ret = baibai_inn_time_counter_1(S, input_tpl)
[print(r) for r in ret]
"""
10㎡?がまんじゅうで一杯になるのに90分要します。
100㎡?がまんじゅうで一杯になるのに105分要します。
東京ドームがまんじゅうで一杯になるのに175分要します。
地球がまんじゅうで一杯になるのに420分要します。
太陽がまんじゅうで一杯になるのに835分要します。
"""

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/04 20:50

    ご回答頂きありがとうございます。
    また、コードの不手際までご指摘頂きましてありがとうございます。

    一点確認なのですが、
    http://www.freia.jp/taka/blog/python3-hash-randomie/index.html
    上記サイトでは
    >Python3.6では、辞書のキー順を維持するので、hash値がどうであっても結果は固定化されます

    とありますがこちらpythonのバージョンによって辞書のorderが不定か固定か異なるという認識でよろしいでしょうか。

    キャンセル

  • 2019/04/04 20:59

    はい。3.6以降の(CPythonの)実装仕様上では固定です。
    3.7が出ている最近ではあまり気にする必要はないのかもしれませんが、古いマシン・OS環境では一応注意しておく必要があります。

    キャンセル

  • 2019/04/05 09:54

    ありがとうございます。

    キャンセル

+1

  1. 辞書のことは一旦忘れて、場所の名前と面積を入れると何分で一杯になるか出力する関数を書く
  2. その関数を辞書の要素それぞれに対して実行する。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

汎用性はないし、雑なコードですが、何かの課題っぽいのでこれで良いのではないでしょうか。

import numpy as np
import pandas as pd
def baibai_inn_time_counter_1 (entry_object, target_dic):

    count = 0
    res = []

    while True:
        for key, value in target_dic.items():
            if entry_object * 2 ** count/5  > value:
                res.append("{key}がまんじゅうで一杯になるのに{count}分要します。".format(key = key, count = count))
            else:
                count += 5
            if len(res)==3:
                return res

出力結果

['東京ドームがまんじゅうで一杯になるのに45分要します。',
 '東京ドームがまんじゅうで一杯になるのに55分要します。',
 '東京ドームがまんじゅうで一杯になるのに65分要します。']

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/04 15:28

    あ、課題なら答え出したらいけないのか汗
    ちなみに、知り合いがドラえもんの栗饅頭の話で宇宙を多い尽くすのにかかる時間を計算したことがありますが、だいたい17-18時間くらいでしたね笑

    キャンセル

  • 2019/04/04 15:31

    ありがとうございます!

    ただそれであっても
    ['東京ドームがまんじゅうで一杯になるのに45分要します。'
    '地球がまんじゅうで一杯になるのに●分要します。'
    '太陽がまんじゅうで一杯になるのに△分要します。']

    というのが求めたい出力でした!

    キャンセル

  • 2019/04/04 16:56

    そのような形にしたいだけなら、以下を追加すればいけますよ。
    print('['+res+']')

    キャンセル

0

解決済み

def baibai_inn_time_counter (entry_object, target_dic):

    count = 0
    declare = []

    for key, value in target_dic.items():
        while entry_object * 2 ** (count/5)  < value:
            count += 5
        else:
            print("{target}がまんじゅうで一杯になるのに{time}分要します。".format(target = key, time = count))

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

同じタグがついた質問を見る