gaya_udonのブログ

学んだことを自分の言葉にすることで理解が深まると思ったので、ブログ開設しました。主にPythonについて学習したことを書こうと思います。

C言語の基礎

これからC言語についての勉強が始まるのでまとめる形で書きます。


 Pythonは割と自動で機会が行ってくれるのが多く、楽だったのですがC言語は全部自分で処理しなければならないので難しいと感じました。それを書きます。

・変数を使う前には型の宣言をする。
これはPythonではいらなかったので慣れる様に頑張ります。
例えば整数型の場合は int 変数名
   文字列型の場合はstr 変数名
などです。この宣言をしないと変数は使えません。

・関数を作る前に型の宣言をする。
関数を作る前には戻り値の型の宣言をする必要があります。
整数の戻り値の関数を作る場合、
int main()
{

.....

}

になります。

・関数の引数の前に型の宣言をする。
関数名(型 引数, 型 引数)
この様な形になります。

・文末にはセミコロンが必要。
関数の中の文末には全て;を入れる必要があります。これは忘れない様に注意します。
;をつけるのはPythonでいうところのインデントにあたります。

・変数に途中で違う型の値を入れることはできない。
Pythonでは可能でしたが、Cでは不可能です。

・printfについて
printfという関数は、の前に,のあとの値を埋め込んでいく関数です。
printf(”私の名前は%sです。身長は%dcmです。体重は%dkgです。", 伊藤太郎, 182, 70)
この様に使います。文字列を埋め込む場合は%s。整数を埋め込む場合は%dを使います。

・scanfについて
scanfという関数はPythonでいうところの変数=int(input())にあたります。
scanf("%d",&変数名)と使います。
こうすることで入力した値を変数名に代入します。

・文字列を囲むときは""を使う。
絶対に""でなければなりません。''で囲むことはできません。

・1つのプログラムに関数を2つ以上使う場合、後ろにある関数を前にある関数の中で使いたい場合、関数の宣言をしなければならない。
プログラムは上から下に動作していくので上にある関数の中で下にある関数を使いたい場合には宣言しないとエラーになります。
その時には、使いたい関数の戻り値の型の宣言もしなければなりません。


全体的に型の宣言をするんだなという印象です。
Pythonよりも書かなければならないことが多いので注意深く勉強していこうと思います。

Pythonを使った1~999までの数字を与えると英語に直す関数

こんにちは。

今日はPythonを使った数字を与えると英語に直す関数を作りました。
一見簡単そうな関数ですが作ってみると必要な要素が多く、苦戦しました。
では、書いたプログラムの説明に入ります。
数字を英語にするには規則性を見つけてそれを埋めていくだけでいいのでは?と思ったのですが、そう上手くはいかず、11や12はeleven、twelveと来て、また13~19もthirteenだとかfifteenだとか例外なんですね。
そこで、10番代は規則性の例外になるのでそこのリストも作ろうと考えました。
これにてリストの定義についてはお終いです。
次に苦戦したのが、引数の調べ方です。
引数として与えた数字を分解して考えるのでこれをPythonでどうやって分解しようかと思いました。(Excelの場合は関数のleftなどを使えば一発で済むのに。。。)
そこで、整数のみの割り算や割り算の余りを求める演算子が使えると気が付き3桁の数字を分解することが出来ました。
後は簡単ですね。if文で条件を見てそれに沿った返し分を入れるだけです。このif文も短くなる気はしますが、、、(今の自分ではこれが精いっぱいです。)

def num_to_str(n):
   a = ["one","two","three","four","five","six","seven","eight","nine"]
   b = ["ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"]
   c = ["eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"]

#100の位の計算(nを100で割った整数を求める)
d = n // 100
#10の位の計算(nからd * 100の値を引いた数を10で割った整数を求める)
e = (n - d * 100) // 10
#1の位の計算(nからd * 100の値を引いた数を10で割った余りを求める)
f = (n - d * 100) % 10

if n >= 11 and n <= 19:  #nが11~19の数かを調べる
     return c[n-11]
elif d  == 0:   #100の位があるか調べる
      if  e == 0: #10の位があるか調べる
            return a[f-1]
      elif f == 0: #1の位があるか調べる
            return b[e-1]
      else: 
            return b[e-1] + "-" + a[f-1]
elif e == 0:
     if f == 0:
           return a[d-1] + " hundred"
     else:
           return a[d-1] + " hundred and " + a[f-1]
else:
     if f == 0:
          return a[d-1] + " hundred and " + b[e-1]
     else:
          return a[d-1] + " hundred and " + b[e-1] + "-" + a[f-1]


実行例
num_to_str(903)
>>>"nine hundred and three"
num_to_str(18)
>>>"eighteen"

うまく作動しました!
ありがとうございました。

16進数の変換について

こんにちは。
今日は16進数の変換ついて書いていきたいと思います。
まず、16進数の他にも2進数だとか10進数とかがあることは知っています。
2進数は0,1のみで数字を表す形です。主にコンピュータで使用されていますね。
10進数は皆がお馴染みの0~9まである形ですね。
そこで2進数と10進数について復習から始めていこうかなと思います。

2進数を10進数に変換
やり方として、2進数のすべての位にその位の今何乗かをかけてあげるやり方があります。
11010という数字を10進数に直してみようと思います。

    2進数  1   1   0   1   0
    何乗か  2⁴  2³  2²  2¹  2⁰

このように0乗から始まっていきます。
次に下の段×2進数の数をして、その結果を足していきます。
1 * 2⁴ + 1 * 2³ + 0 * 2² + 1 * 2¹ + 0 * 2⁰
=26
となるので、2進数11010の10進数は26となります。

10進数を2進数に変換
こっちは比較的簡単で、2進数で与えた数を2で割れなくなるまで割っていくだけです。
例えば、先ほどと同じように10進数の26を与えてあげます。
計算すると、

26 / 2 = 13...0
13 / 2 = 6 ...1
6 / 2 = 3 ...0
3 / 2 = 1 ,,,1
1

となり、答えは11010となります。

次に、今回のテーマでもある16進数についてです。
16進数は16種類の数字が使われるのですが、数字というのは0~9までしかありません。
そこで、アルファベットのA,B,C,D,E,Fを数字として使います。
並べてみると、0 1 2 3 4 5 6 7 8 9 A B C D E F 10
となります。

2進数を16進数に変換
この変換をする場合には、まず2進数を4桁ごとに区切って計算する必要があります。
例として、10011011を16進数に変換してみます。
まず数字を4桁に区切ります。
1001 | 1011
ここから先の作業は2進数を16進数に変換するやり方と同じです。

1  0  0  1    |    1  0  1  1
2³ 2² 2¹ 2⁰   |   2³ 2² 2¹ 2⁰

8+0+0+1   |  8+0+2+1

=9B
となります。

16進数を2進数に変換
この変換は10進数を2進数に変換する方法を分けてやるだけで出来ます。

   9 B B= 11
9 / 2 = 4...1 11 / 2 = 5...1
4 / 2 = 2...0 5 / 2 = 2...1
2 / 2 = 1...0 2 / 2 = 1...0
1 1

1001 1011
=10011011

16進数を10進数に変換
これも2進数を10進数に変換するやり方を分解してやるだけです。

 9B
B=11

  9  11
  16¹  16⁰
9 * 16¹ + 11 *16⁰
=155

10進数を16進数に変換

155

155 / 16 = 9...11
=9B

変換は2進数と10進数の変換が出来れば16進数も同じなので大丈夫ですね。

Python もし文字列型(str型)で要素の書き換えがでるとどうなるか?

こんにちは。
今回は文字列(str型)で要素の書き換えができるとどのようになるかについてです。
はじめに、文字列(str型)とリストはよく似ています。
そこで、forループで文字列を取り出してみようと思います。

#文字列(str型)
s = "hello"
for c in s:
    print(c)
h
e
l
l
o

#リスト
s = ["h","e","l","l","o"]
for c in s:
   print(c)
h
e
l
l
o

と、このようになります。
forループについてはどちらも問題なく動作しましたね。
次に、要素の書き換えをしてみます。

#リスト
s = ["h","e","l","l","o"]
s[0] = "k"
s
["k","e","l","l","o"]

#文字列(str型)
s = "hello"
s[0] = "k"
s
Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    s[0] = "k"
TypeError: 'str' object does not support item assignment

はい。このようにリストを使った場合は要素の書き換えはできますが、文字列(str型)の場合はできないようになっています。
そこで、もし文字列(str型)で要素の書き換えができるようになるとどうなるのかを考えていきたいと思います。

メリット・・・  単純に変数に文字列を入れてミスした場合の修正が簡単になるのではないかなと思います。

デメリット・・・ 文字列の書き換えが出来るということはつまり、可変性を持つ型になり後の操作により文字列をコピーした際片方を操作した場合にもう片方も変わってしまうということになります。

結論・・・  文字列(str型)は変数名として文字列を使った場合(例えばresultなど)に文字列に可変性を持っていると変数として使えなくなるので不変性を持つ型なのかなと思いました。
ありがとうございました。

Pythonを使った画面に高さnのピラミッドを表示する関数

こんにちは。

今回の問題は高さnを指定すると、その高さのピラミッドを表示するプログラムです。

 

この関数自体は作れているのですが、今回ーは作り方のお話です。

f:id:gaya_udon:20181115235739p:plain

この関数は、一番初めに完成した関数です。

このやり方だとforループやrange関数の強みを生かせていません。

というわけで、、、

f:id:gaya_udon:20181115235955p:plain

これは次に作った関数です。

この関数であれば、forループ、range関数の強みを生かせており、プログラムも簡潔書かれていますね。

しかし、forの入れ子にすればもっと短くなるのでは?と考えました。

 

f:id:gaya_udon:20181116002139p:plain

それがこのプログラムです。

しかし、いざ実行してみると、、、

f:id:gaya_udon:20181116002308p:plain

うーーーーーん。...

あれ?と悩みに悩んだ結果、気づきました。

この関数、入れ子いらなくね?

f:id:gaya_udon:20181116002616p:plain

 

実行してみると、、、

f:id:gaya_udon:20181116002810p:plain

はい。完成しました!

入れ子なんていらなかった。

入れ子にこだわっていた時間が馬鹿らしいですが、自分で気づけたのでよしです。

ありがとうございました。