コンソールで機能を構築します。 パート1

画像



ほとんどの場合、合理的な質問があります:なぜですか?



実用的な観点からは、必要はありません)条件付きタングステンをいつでも使用できます。Pythonでこれを行う必要がある場合は、それほど難しくない特別なモジュールを使用してください。



しかし、あなたが突然そのようなタスクを与えられた場合、またはあなたが私のようなプログラミングが本当に好きな場合、あなたはエキサイティングな-そして時には非常に-何時間もプログラムを書いてデバッグするでしょう)



この傑作を書くときは、段階的なデバッグが本当に必要なので、PyCharm、VS、またはこの機能を備えた何かをダウンロードしてください。 テーブルを構築するために、この関数の欠如はそれほど重要ではありませんが、プロットのために...



それで、私のプログラムはどうなりますか。 入力では、関数を表示するセグメントの開始と終了、および移動するステップの3つの値を取ります。 次に、入力データで指定された値の範囲から各ポイントの関数値のテーブルを描画します。 それでは、関数自体のグラフを移動するy軸で描画します。



さあ行こう



まず、値を考慮するいくつかの関数を宣言します。 私は特に非常にシンプルに取ります



from math import sqrt def y1(x): return x**3 - 2*x**2 + 4*x - 8 def y2(x): return 1 - 1/x**2 def y3(x): return sqrt(abs(y1(x)*y2(x)))
      
      





これで3つの関数ができました。そのうちの2つにブレークポイントがあります。 すべての数学バン(余弦、逆正接、および他の三角法を含む)を格納する数学モジュールから、sqrt、つまり平方根をインポートします。 関数y3を読み取るために必要です。



その後、xによる関数の範囲と、この範囲を通過するステップを読み取る必要があります。 このために、マップを使用します。



この関数は、最初のパラメーターとして、必要なデータを何らかの形で変換する関数を受け入れ、2番目の引数として、処理する必要がある何らかのデータシートを受け入れます



 from_x, to_x, pace_x = map(float, input("Enter the first and the last"\ " x-coordinates and a pace dividing them by a"\ " space:").split())
      
      





スペースを介して入力された3つの値を読み取り、スペースで要素に分割します(パラメーターを指定せずに呼び出すと、指定した文字列をスペースで自動的に分割するsplitメソッドを使用します)。 input()を使用して入力されたデータは、デフォルトではstr型、つまり文字列であるため、ここでエラーは発生しません。



範囲の境界番号は小数になる可能性があるため、float関数を使用して、結果の配列の各要素を実数に変換します。



変数はデータ型を指定せずに宣言されることに注意してください。 これは、自動的に(変数に割り当てようとしている値のデータ型)、またはstr、int、floatなどの関数を使用して決定されます。 変数によって手動で設定し、これらの同じ関数を値に適用します。 プログラム全体で同じ変数は異なるデータ型を持つことができます-このため、異なるデータ型の新しい値を割り当てるだけで十分です



例えば



 auxiliary_variable = "" #   str auxiliary_variable = 2 #   int auxiliary_variable = 9.218 #   float
      
      







プログラムに戻りましょう。 入力したデータが正しいかどうかを確認する必要があります。



次の場合、プログラムは入力されたデータが正しくないことを印刷する必要があります。





これらの条件をコードで定式化します。 明らかに、最初の項目は簡単に設定できます。 最初(from_x)と最後(to_x)の差の符号がステップの符号と一致する必要があることに気づいた場合、2番目と3番目を1つに結合できます。 まあ、4番目のポイントもそれほど複雑ではありません。最初と最後の値の差のモジュラスは、stepモジュール以上でなければなりません。



モジュールのために、差とステップの兆候が一致しない場合がありますが、2番目の条件はこれらのケースをカットするので、条件は正しいです。



その結果、これらの3つの条件は次のようになります。



 if (pace_x != 0) and (to_x - from_x)*pace_x >= 0 and abs(to_x - from_x): #-  else: print("Incorrect input")
      
      





テーブルに直接進みます。 デバッグを容易にするために、数字の正確さ、数字の前のスペースの数、数字の後ろのスペースの数などを担当する名前を話す変数をいくつか作成します。



 dials_precision = "%10.6g" #   spaces_in_the_title = int((int(dials_precision[1:3])) / 2) length_of_table_lower_bound = (int(dials_precision[1:3]) + 2) * 4 + 5 delimiter = ' ' is_sequence_decreasing = to_x - from_x < 0 min_y1_value, max_y1_value, x_copy = y1(from_x), y1(from_x), from_x negative_value_exists = False
      
      





ここで何が起こっているのでしょうか?



画像



 dials_precision = "%10.6g" #  
      
      





この行では、数値の精度を設定します。 整数には最大10文字、小数部には最大6文字。 この範囲に対して値が大きすぎると、あらゆる種類のe-15または類似の何かが表示されます。



 spaces_in_the_title = int((int(dials_precision[1:3])) / 2)
      
      





dials_precisionは文字列なので、この文字列のスライス、つまりある種の部分文字列を取得できます。 この場合、数字10を取得する必要があるため、1と2のインデックスの文字を取得し、このサブストリングを整数データ型に変換し、2で除算して切り捨てます。



テーブルの見出しの碑文がセルの中央にくるように、この変数が必要です



 length_of_table_lower_bound = (int(dials_precision[1:3]) + 2) * 4 + 5
      
      





名前が示すように、この変数は、関数の値のテーブルのセルの下限の長さを担当します。 合計で10桁を占めるため、列の幅を10未満にすることはできません。e-15形式(上記)で数値を取得する場合、値は11〜12桁になります。 したがって、10に別のデュースを追加します。



4は列数(x、y1、y2、y3)を担当し、5は行内のセルを制限する文字数を担当します。



残りの変数は直感的なようですので、プレートの印刷に移りましょう



 print("|" + (spaces_in_the_title + 1) * delimiter + 'x' + spaces_in_the_title * delimiter + '|' + spaces_in_the_title * delimiter + "y1" +\ spaces_in_the_title* delimiter\ + '|' + spaces_in_the_title * delimiter + 'y2'\ + spaces_in_the_title * delimiter + '|' +\ spaces_in_the_title * delimiter\ + "y3" + spaces_in_the_title * delimiter + "|\n"\ + length_of_table_lower_bound * '-')
      
      





すでに作成したすべてのコードを接続すると、コンソールに次のように表示されます。



画像



次に、値自体を印刷する必要があります。 これを行うには、サイクルが必要です。 入力されたデータは分数である可能性があるため、 範囲の使用は機能しないため、通常のループを使用します。



Xの減少シーケンスと増加シーケンスの両方を使用できるため、これらのオプションの両方が考慮されるようにサイクル条件を設定する必要があります。 シーケンスの性質に関する回答を0または1の形式で保存する、以前に作成された変数があります。したがって、2つのケースを考慮し、それぞれに適切な条件を選択するだけで十分です。



 while(is_sequence_decreasing and x_copy >= to_x) or\ (not is_sequence_decreasing and x_copy <= to_x):
      
      





グラフにはグラフy1の最小値と最大値が必要なので、これを描画するため、minとmaxを担当する特別な変数を導入します



 y1_cur_value = y1(x_copy) min_y1_value = (min_y1_value > y1_cur_value) * y1_cur_value + \ (min_y1_value <= y1_cur_value) * min_y1_value max_y1_value = (max_y1_value < y1_cur_value) * y1_cur_value + \ (max_y1_value >= y1_cur_value) * max_y1_value negative_value_exists += y1_cur_value < 0
      
      





本質的に、構築はif:... else:...の構築をブール不等式のみで繰り返します。 y1_cur_valueは、関数の現在の値を格納します。 ある時点での値が必要なときに関数を絶えず呼び出さないように、変数を作成しました。

また、プロットには負の値が必要です。



画像



ここで、値を直接印刷します。 すべてを美しく、各セルの中央に配置したいので、各値を手動で処理して数値の長さを確認し、それに応じてスペースの数を選択して値を揃える必要があります。



ご注意

文字列の中央揃えは機能しません。 精度の原因となる変数のパラメーターはgです。 彼は、特定の数のポジションが数字のために予約されていると言います(この場合、デフォルトでは10)。 10桁がダイヤルされない場合、空白の位置は塗りつぶされた位置の左側に配置されます。 したがって、中央に配置できるのは10の位置の行のみです。





 aux_x = dials_precision % x_copy aux = len(aux_x) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_x) == int(dials_precision[1:3]) + 1 print('|' + delimiter * aux + aux_x + delimiter * (aux - aux_2) + '|', end='')
      
      



aux_x-指定された精度でビューにすでに取り込まれている文字列。 次に、数字の長さを確認し、必要な数のスペースを選択する必要があります。 各側から複数のスペースが必要ないため、 bool eva変数はこれらのスペースの数の保護者として完璧です。 aux_2は、数値の長さが11の場合にキャッチします。



また、3つの関数の値についても行います



  aux_y1 = dials_precision % y1_cur_value aux = len(aux_y1) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y1) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y1 + delimiter * (aux - aux_2) + '|', end='') if (x_copy != 0): aux_y2 = dials_precision % y2(x_copy) aux = len(aux_y2) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y2) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y2 + delimiter * (aux - aux_2) + '|', end='') aux_y3 = dials_precision % y3(x_copy) aux = len(aux_y3) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y3) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y3 + delimiter * (aux - aux_2) + \ "|\n" + length_of_table_lower_bound * '-') else: print((spaces_in_the_title - 2) * delimiter + " " \ + (spaces_in_the_title - 2) * delimiter + '|' \ + (spaces_in_the_title - 2) * delimiter + " " \ + (spaces_in_the_title - 2) * delimiter + "|\n" \ + length_of_table_lower_bound * '-') x_copy += pace_x
      
      





冒頭で述べたように、2番目と3番目の関数にはブレークポイントがあります。両方の関数はx = 0のポイントには存在しません。したがって、これらのケースもキャッチする必要があります。



無限ループが発生しないように、現在のx値を増やすことを忘れないでください。



1つのプログラムですべてのコードを収集し、たとえば-1.2 3.6 0.3テストで実行してみましょう



画像



 from math import sqrt def y1(x): return x**3 - 2*x**2 + 4*x - 8 def y2(x): return 1 - 1/x**2 def y3(x): return sqrt(abs(y1(x)*y2(x))) from_x, to_x, pace_x = map(float, input("Enter the first and the last"\ " x-coordinates and a pace dividing them by a"\ " space:").split()) if (pace_x != 0) and (to_x - from_x)*pace_x >= 0 and abs(to_x - from_x): dials_precision = "%10.6g" #   spaces_in_the_title = int((int(dials_precision[1:3])) / 2) length_of_table_lower_bound = (int(dials_precision[1:3]) + 2) * 4 + 5 delimiter = ' ' is_sequence_decreasing = to_x - from_x < 0 min_y1_value, max_y1_value, x_copy = y1(from_x), y1(from_x), from_x negative_value_exists = False print("|" + (spaces_in_the_title + 1) * delimiter + 'x' + spaces_in_the_title * delimiter + '|' + spaces_in_the_title * delimiter + "y1" + spaces_in_the_title * delimiter \ + '|' + spaces_in_the_title * delimiter + 'y2' \ + spaces_in_the_title * delimiter + '|' + spaces_in_the_title * delimiter \ + "y3" + spaces_in_the_title * delimiter + "|\n" \ + length_of_table_lower_bound * '-') while (is_sequence_decreasing and x_copy >= to_x) or \ (not is_sequence_decreasing and x_copy <= to_x): y1_cur_value = y1(x_copy) min_y1_value = (min_y1_value > y1_cur_value) * y1_cur_value + \ (min_y1_value <= y1_cur_value) * min_y1_value max_y1_value = (max_y1_value < y1_cur_value) * y1_cur_value + \ (max_y1_value >= y1_cur_value) * max_y1_value negative_value_exists += y1_cur_value < 0 aux_x = dials_precision % x_copy aux = len(aux_x) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_x) == int(dials_precision[1:3]) + 1 print('|' + delimiter * aux + aux_x + delimiter * (aux - aux_2) + '|', end='') aux_y1 = dials_precision % y1_cur_value aux = len(aux_y1) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y1) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y1 + delimiter * (aux - aux_2) + '|', end='') if (x_copy != 0): aux_y2 = dials_precision % y2(x_copy) aux = len(aux_y2) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y2) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y2 + delimiter * (aux - aux_2) + '|', end='') aux_y3 = dials_precision % y3(x_copy) aux = len(aux_y3) != int(dials_precision[1:3]) + 2 aux_2 = len(aux_y3) == int(dials_precision[1:3]) + 1 print(delimiter * aux + aux_y3 + delimiter * (aux - aux_2) + \ "|\n" + length_of_table_lower_bound * '-') else: print((spaces_in_the_title - 2) * delimiter + " " \ + (spaces_in_the_title - 2) * delimiter + '|' \ + (spaces_in_the_title - 2) * delimiter + " " \ + (spaces_in_the_title - 2) * delimiter + "|\n" \ + length_of_table_lower_bound * '-') x_copy += pace_x else: print("Incorrect input")
      
      





この作成の2番目の部分では、グラフを作成します



画像



継続するには...



All Articles