- 投稿日:2021-08-09T23:58:30+09:00
Swift初学者が自動販売機ロジックを書いてみたら2…(リファクタリング後)
今回は自動販売機ロジックについて学習したのでアウトプットします。 今回はその2回目です。 ちなみに私はMac触り始めて半年の者です。(ガチガチの初心者です) 初学者のアウトプット記事ですので、間違っている点など多々あるかと思いますが、暖かい目で見守っていただけますと幸いです。 はじめに 現在、私はMENTAで、ヤマタクメンターにご指導いただいております。 ヤマタクメンターのURL https://menta.work/user/1840 今回は課題として、自動販売機のロジックをXcodeのPlaygroundでコーディングしてみました。 簡単に言うと自動販売機の仕組みをコードで表現しましたみたいなことですね。 第一回目のコード Swift初学者が自動販売機ロジックを書いてみたら…(その1) 一発目から一回リファクタリングしてみたんですが、どうも納得いかなくてサンプルコードを参考にして、結局2回くらい書き直しました。 仕様 ・お金を入力する ・お金は1、5、10、50、100、500、1000円から何枚入力するか指定する ・1、5円は使用不可、その他のお金のみ使用可能とする ・水、コーヒー、エナジードリンクの3種類から指定する ・飲み物が買われたら、その飲み物の在庫数を-1して、お釣りを出力 ・お金が足りなければ、お金が足りません!と出力 ・在庫がなければ、すみません!在庫がありません!と出力 実装コード VendingMachine.playground import UIKit //ドリンクの種類と金額 enum DrinkType { case coffee case water case energyDrink var price: Int { switch self { case .coffee: return 150 case .water: return 100 case .energyDrink: return 200 } } } struct DrinkModel { var type: DrinkType var stock: Int } struct calculateMoney { var inputedYen: Int = 0 var change:Int = 0 enum Money: Int { case oneYen = 1 case fiveYen = 5 case tenYen = 10 case fiftyYen = 50 case onehundredYen = 100 case fivehundredYen = 500 case onethousandYen = 1000 } func MoneyCount(moneyType: Money,count: Int) -> Int { switch moneyType { case .oneYen: return Money.oneYen.rawValue * count case .fiveYen: return Money.fiveYen.rawValue * count case .tenYen: return Money.tenYen.rawValue * count case .fiftyYen: return Money.fiftyYen.rawValue * count case .onehundredYen: return Money.onehundredYen.rawValue * count case .fivehundredYen: return Money.fivehundredYen.rawValue * count case .onethousandYen: return Money.onethousandYen.rawValue * count } } //使用不可のお金が入力されているか判別 func selectDisabledMoney() -> Bool { guard oneYenCalculate > 0 || fiveYenCalculate > 0 else { return false } return true } //使用不可のお金は出力して、使用可能なお金はinputedYenとして代入する mutating func checkInputedYen() { if selectDisabledMoney() { inputedYen = tenYenCalculate + fiftyYenCalculate + onehundredYenCalculate + fivehundredYenCalculate + onethousandYenCalculate print("1円と5円は使用できません。\(oneYenCalculate + fiveYenCalculate)円お返しします。") }else{ inputedYen = tenYenCalculate + fiftyYenCalculate + onehundredYenCalculate + fivehundredYenCalculate + onethousandYenCalculate } } mutating func calculateChange(money: Int,price: Int) { change = money - price } } var calculate = calculateMoney() //何円を何枚使用するか入力 let oneYenCalculate = calculate.MoneyCount(moneyType: .oneYen, count: 0) let fiveYenCalculate = calculate.MoneyCount(moneyType: .fiveYen, count: 0) let tenYenCalculate = calculate.MoneyCount(moneyType: .tenYen, count: 0) let fiftyYenCalculate = calculate.MoneyCount(moneyType: .fiftyYen, count: 0) let onehundredYenCalculate = calculate.MoneyCount(moneyType: .onehundredYen, count: 0) let fivehundredYenCalculate = calculate.MoneyCount(moneyType: .fivehundredYen, count: 0) let onethousandYenCalculate = calculate.MoneyCount(moneyType: .onethousandYen, count: 1) //ドリンクが購入できることを確証する protocol BuyDrinkValidatable {} extension BuyDrinkValidatable { func validateDrinkBuyable(with drink: DrinkModel,inputYen: Int,change: Int) -> Bool { if drink.stock > .zero && drink.type.price <= inputYen && change >= 0 { return true }else{ return false } } } class VendingMachine: BuyDrinkValidatable { // ドリンクの初期在庫数 var coffee = DrinkModel(type: .coffee, stock: 5) var water = DrinkModel(type: .water, stock: 5) var energyDrink = DrinkModel(type: .energyDrink, stock: 5) // ドリンクを購入する関数 func buyDrink(type: DrinkType, inputedYen: Int) -> Bool { calculate.checkInputedYen() switch type { case .coffee: let isBuyable = validateDrinkBuyable(with: coffee, inputYen: calculate.inputedYen, change: calculate.change) if isBuyable { reduceStock(type: type) calculate.calculateChange(money: calculate.inputedYen, price: DrinkType.coffee.price) print("\(type)をどうぞ!\(calculate.change)円のお返しです!") }else if coffee.stock == .zero{ print("すみません在庫切れです!\(calculate.inputedYen)円お返しします") }else{ print("お金が足りません!\(calculate.inputedYen)円お返しします") } return isBuyable case .water: let isBuyable = validateDrinkBuyable(with: water, inputYen: inputedYen, change: calculate.change) if isBuyable { reduceStock(type: type) calculate.calculateChange(money: calculate.inputedYen, price: DrinkType.water.price) print("\(type)をどうぞ!\(calculate.change)円のお返しです!") }else if water.stock == .zero{ print("すみません在庫切れです!\(calculate.inputedYen)円お返しします") }else{ print("お金が足りません!\(calculate.inputedYen)円お返しします") } return isBuyable case .energyDrink: let isBuyable = validateDrinkBuyable(with: energyDrink, inputYen: inputedYen, change: calculate.change) if isBuyable { reduceStock(type: type) calculate.calculateChange(money: calculate.inputedYen, price: DrinkType.energyDrink.price) print("\(type)をどうぞ!\(calculate.change)円のお返しです!") }else if energyDrink.stock == .zero{ print("すみません在庫切れです!\(calculate.inputedYen)円お返しします") }else{ print("お金が足りません!\(calculate.inputedYen)円お返しします") } return isBuyable } } // 在庫を減らす関数 func reduceStock(type: DrinkType) { switch type { case .coffee: coffee.stock -= 1 case .water: water.stock -= 1 case .energyDrink: energyDrink.stock -= 1 } } } let activateVendingMachine = VendingMachine() //type引数にドリンク名を入れる activateVendingMachine.buyDrink(type: .coffee, inputedYen: calculate.inputedYen) おわりに 反省点として、 ・実装予定だった釣り銭切れの機能が実装できなかった ・ドリンクとお金の入力箇所が離れている ・キレイにまとめるつもりが、結果的に可読性の低いコードになってしまった 釣り銭切れの機能は、釣り銭が100円だとしたら、 100円1枚、50円2枚、10円10枚、10円5枚と50円1枚と、100円だけでも4パターン考えられ、1000円以上入力されるとなると、全てのパターンを網羅する必要があり、良い方法を見つけることができなかったので諦めました…泣 また、ユーザーの入力箇所が離れているのと、コードが冗長で、可読性が低いなと感じました。 他にも、汎用性や拡張性はどうなの?とか考えているとキリがないですし、今回のビジネスロジック実装でとても勉強になったので、気を取り直して次の課題に進みます!
- 投稿日:2021-08-09T22:59:16+09:00
M1 MacにPython3をインストールする
はじめに Apple M1チップ搭載のMac Book ProにPython3をインストールした時のメモです。 今回はMiniforgeを利用しました。 やり方 Miniforgeとは最小限のCondaのインストーラーです。 さまざまはCPUアーキテクチャのサポートに重点を置いているので、新しいCPUアーキテクチャのPCにCondaを入れるときに最適です。 今回は直接ダウンロードする方法を紹介します。 1. Githubからダウンロードする。 ここからOS X arm64 (Apple Silicon)Miniforge3-MacOSX-arm64を選択してダウンロードします。 2. 以下をターミナルで実行します。ここではzshを選択しています。 選択肢は全てyesを選択します。 cd Downloads/ bash Miniforge3-MacOSX-arm64.sh 3. 赤線の部分のPathにある.bash_profileを開いて全てコピーする。 Condaのインストールがうまくいっていれば以下のようなものが書き込まれているはずです。 # >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/Users/***/miniforge3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/Users/***/miniforge3/etc/profile.d/conda.sh" ]; then . "/Users/***/miniforge3/etc/profile.d/conda.sh" else export PATH="/Users/***/miniforge3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<< これを全てコピーします。 4. ~/.zsh_profile にコピーした内容を書き込む vim ~/.zsh_profile source ~/.zsh_profile これで成功していれば以下を実行できるはずです。 conda -V 5. CondaでPythonをインストールする conda create -n py3.8 python=3.8 conda activate py3.8 まとめ Apple M1チップ搭載のMac Book ProにPython3をインストールしました。
- 投稿日:2021-08-09T19:24:07+09:00
コピペで乗り切るエンジニアがSwiftUIを勉強してみた(ファイル構成について)
さて、前回SwiftUIの実行環境を用意しました。 SwiftUIのファイル構成と軽くソースの解析を 「Hello world」を使って確認していきます。 (前回:コピペで乗り切るエンジニアがSwiftUIを勉強してみた(環境構築編)) ファイル構成について プロジェクトをつくった際にデフォルトでたくさんファイル作成される。 TestHelloWorld TestHelloWorldApp.swift 作成するアプリケーションのエントリポイント。 @mainと記述された箇所が該当。 ContentView.swift 作成するアプリケーションのビューの役割。 画面に表示するボタンや文字を配置する。 Assets.xcassets アプリで使用する画像を格納するフォルダ。 表示したいファイルはここに追加する。 info.plist アプリ内の共通設定。 アイコンやバージョンの設定や権限まわりの設定を設定する。 Preview Content Preview Assets.xcassets TestHelloWorldTests XCTestフレームワークを使ったユニットテストを実装するためのもの。 使い方はまだ分からないので一旦スルーで。 TestHelloWorldTests.swift Info.plist TestHelloWorldUITests XCTestフレームワークを使ったUIテストを記載します。 こちらも使い方はまだ分からないのでスルーで。 TestHelloWorldUITests.swift Info.plist Products 各種ビルド後のアプリケーション本体。 TestHelloWorld.app TestHelloWorldTests.xctest TestHelloWorldUITests.xctest 実行までの流れ 初期起動(エントリーポイント) さて、上記のフォルダ構成で記載した通り、 SwiftUIでは初期起動(エントリーポイント)は 「@main」で指定されるとのこと。 なので、「このプログラムはどこから始まるのかな?」となったら まずは「@main」を探すと良いかと思います。 import SwiftUI @main struct TestMusicLibraryForSwiftUIApp: App { var body: some Scene { WindowGroup { ContentView() } } } エントリポイントであるTestMusicLibraryForSwiftUIApp から呼び出された ContentView も上記フォルダ構成で記載した通り、 画面レイアウトを記述していきます。 下記に記載の通り、Text("Hello, world!").padding() で画面上に「Hello, world!」という文言を表示させます。 また、ContentView_Previews側はプレビュー表示の際に使用されます。 import SwiftUI struct ContentView: View { var body: some View { Text("Hello, world!") .padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } 以上!ひとまずこのくらいで!
- 投稿日:2021-08-09T17:55:32+09:00
【Linux】 screenコマンドの備忘録:最初はこれだけ覚えればオッケー?
screenコマンドとは tmuxに似ていて、以下の用途で使える。 ・ セッションの保存(sshで長時間のジョブを実行するときに助かる) ・ 画面の分割 MacでもLinuxでも大抵デフォルトで入っているらしい。 逆にtmuxは追加で入れないといけないので、できればscreenに慣れておきたい。 一連の流れ 以下は全てUbuntuで実行。 セッション管理 セッション一覧を確認 $ screen -ls No Sockets found in /run/screen/S-user1. セッションを作成(+自動的にセッションに入る) $ screen -S hoge 今セッションの中にいるのかどうかチェック $ echo $TERM # "screen*"だったら内部にいる screen.xterm-256color $ echo $STY # セッション内部のときだけ存在する環境変数 3023174.hoge セッション内部ではctrl-a <cmd> でscreenコマンドを実行することになる。 もともとのctrl-a(カーソルを先頭に移動)はctrl-a aで実行できる。 セッションを抜ける ctrl-a d 一覧を確認してみる $ screen -ls There is a screen on: 3023174.hoge (08/09/2021 05:25:41 PM) (Detached) 1 Socket in /run/screen/S-user1. セッションに入る(以下のどれでもオッケー) $ screen -r 3023174.hoge $ screen -r hoge $ screen -r 3023174 セッションの削除 $ screen -X quit # 今いるセッションを削除して元のターミナルに戻る $ screen -S hoge -X quit # セッション外部にいて、セッション"hoge"を削除する 画面分割 画面分割 ctrl-a S # 水平 ctrl-a | # 垂直 画面移動 ctrl-a tab 虚無の画面に新規ウィンドウ作成(分割でできた新規画面に移動したらまずこれ) ctrl-a c 分割された画面の削除 ctrl-a X # 小文字のxだと画面ロックになるので注意 Tips マウスでスクロールするなら。 $ cat ~/.screenrc termcapinfo xterm* ti@:te@ defscrollback 100000 ctrl-aからctrl-jに変更。 $ cat ~/.screenrc escape ^Jj
- 投稿日:2021-08-09T17:42:58+09:00
Docker Grafana + STRAVA Plugin install
やりたいこと Mac上のParallelsにインストールしたCentOS8にGrafana on Dockerを構築しSTRAVAのデータを表示させる 参考にした手順 DockerおよびDocker Composeのインストール https://qiita.com/cyberblack28/items/0b0ec02bce67a16e2f17 Docker Grafanaのインストール https://techexpert.tips/ja/grafana-ja/ubuntu-linux%E3%81%B8%E3%81%AEgrafana-docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/ mkdir -p /var/lib/grafana/strava chown -R 472:472 /var/lib/grafana docker run -d -p 3000:3000 -v /var/lib/grafana:/var/lib/grafana -e "GF_SECURITY_ADMIN_PASSWORD=******" -e "GF_STRAVA_DS_DATA_PATH=/var/lib/grafana/strava" grafana/grafana コンテナに環境変数がセットされていることを確認する [root@localhost ~]# docker exec -it e00b0c56473c /bin/bash bash-5.1$ set | grep GF GF_PATHS_CONFIG=/etc/grafana/grafana.ini GF_PATHS_DATA=/var/lib/grafana GF_PATHS_HOME=/usr/share/grafana GF_PATHS_LOGS=/var/log/grafana GF_PATHS_PLUGINS=/var/lib/grafana/plugins GF_PATHS_PROVISIONING=/etc/grafana/provisioning GF_SECURITY_ADMIN_PASSWORD=******* GF_STRAVA_DS_DATA_PATH=/var/lib/grafana/strava STRAVAのデータの取得 https://grafana.com/grafana/plugins/grafana-strava-datasource/ [root@localhost ~]# docker exec -it e00b0c56473c /bin/bash bash-5.1$ grafana-cli plugins install grafana-strava-datasource ✔ Downloaded grafana-strava-datasource v1.3.0 zip successfully Please restart Grafana after installing plugins. Refer to Grafana documentation for instructions if necessary. bash-5.1$ exit [root@localhost ~]# docker stop e00b0c56473c e00b0c56473c [root@localhost ~]# docker start e00b0c56473c e00b0c56473c Configre -> Data Sources -> Add data source -> (Find Name)STRAVA STRAVAのMyアプリケーションで認証コールバックドメインに接続しているGrafanaのFQDNかIPを入れること(ポート3000は不要だった) Save & Test -> Connect With STRAVA -> Save & Testと操作しないとうまく登録できなかった。
- 投稿日:2021-08-09T16:37:08+09:00
OSX上でPyCharmをつかってxlwingsを実行するとCommand failed: The user has declined permission. (-1743)エラーになる
現象 PyCharmでxlwingsのプログラムを書こうとすると、以下のエラーが出る。 Command failed: The user has declined permission. (-1743) 実行しようとするコードは以下の通り #!/usr/local/bin/python3.9 # -*- coding: utf-8 import xlwings as xw wb = xw.Book('myexcel.xlsx') 同じプログラムをターミナルから実行すると問題なく動作した。 どうやらPyCharmにOSXのパーミッションが足りないようだ。 この記事を参考にした。 https://intellij-support.jetbrains.com/hc/en-us/community/posts/360005152379-Pycharm-cannot-get-permission-to-control-Excel-Mac- 対応方法 PyCharmをターミナルから起動する。 ターミナルを開いて、以下を実行してPyCharmを起動する。このとき他にPyCharmが起動していればて終了させる。 /Applications/PyCharm.app/Contents/MacOS/pycharm エラーが発生しなくなった。 毎回長いコマンドを入力するのは面倒なので .bashrc に alias を定義。 alias pc='/Applications/PyCharm.app/Contents/MacOS/pycharm' コマンドラインから pc を入力すると PyCharm が起動するようになる。
- 投稿日:2021-08-09T16:37:08+09:00
OSX上でPyCharmをつかってxlwingsを実行するとCommand failed: The user has declined permission. (-1743)エラーになる場合の対応策
現象 PyCharmでxlwingsのプログラムを書こうとすると、以下のエラーが出る。 Command failed: The user has declined permission. (-1743) 実行しようとするコードは以下の通り #!/usr/local/bin/python3.9 # -*- coding: utf-8 import xlwings as xw wb = xw.Book('myexcel.xlsx') 同じプログラムをターミナルから実行すると問題なく動作した。 どうやらPyCharmにOSXのパーミッションが足りないようだ。 この記事を参考にした。 https://intellij-support.jetbrains.com/hc/en-us/community/posts/360005152379-Pycharm-cannot-get-permission-to-control-Excel-Mac- 対応方法 PyCharmをターミナルから起動する。 ターミナルを開いて、以下を実行してPyCharmを起動する。このとき他にPyCharmが起動していればて終了させる。 /Applications/PyCharm.app/Contents/MacOS/pycharm エラーが発生しなくなった。 毎回長いコマンドを入力するのは面倒なので .bashrc に alias を定義。 alias pc='/Applications/PyCharm.app/Contents/MacOS/pycharm' コマンドラインから pc を入力すると PyCharm が起動するようになる。
- 投稿日:2021-08-09T12:11:45+09:00
スマートホーム目指してラズパイ触ってみた(2) 〜Macからリモートデスクトップ接続編〜
今回の目標 ・MacからMicrosoft Remote Desktopを使用してラズパイにアクセスできるようになる 他の記事はこちら スマートホーム目指してラズパイ触ってみた(1) 〜ラズパイ4+SenseHatセットアップ編〜(Qiita) スマートホーム目指してラズパイ触ってみた(3) 〜LINE連携&温度通知編〜(Qiita) スマートホーム目指してラズパイ触ってみた(4) 〜Amazon S3連携編〜(Qiita) スマートホーム目指してラズパイ触ってみた(5) 〜Amazon S3 + QuickSight連携編〜 (Qiita) Step1 ラズパイをさわるのに毎回HDMIケーブルやら有線キーボードを接続するのは面倒・・・ということで、MacからRemoteDesktopでアクセスできるようにします。 ラズパイ側でソフトウェアのインストールが必要になるので、ターミナルを起動し、以下のコマンドを実行します。 sudo apt-get install xrdp sudo service xrdp restart インストールが完了したら、 ラズパイのターミナルでifconfigを実行し、ラズパイのIPアドレスを確認する リモートデスクトップのアプリから、ラズパイのIPアドレスを指定してリモートデスクトップ接続します。 私はMacから接続したかったので、こちら(Mac版のMicrosoft Remote Desktop)を使いました。 ※ラズパイと自分のPCが同じWifiに接続してないと(所属するネットワークが異なるため)、リモートデスクトップ出来ないので注意です。 PC name: ラズパイのIPアドレス(Wifi接続用) User Account: pi (ラズパイのデフォルトrootユーザー) Password: ラズパイのパスワード 私の設定画面はこんな感じです。 参照記事
- 投稿日:2021-08-09T06:47:31+09:00
Macで定期的にcsvファイルをDLして任意の名前をつけて保存する
社内のツールやクラウドツールなどからcsv形式のファイルをDLする業務を自動化したい ツール側で定期DLの仕組みがなくローカルで自動化する必要があるとする Macの場合はopenコマンドを利用してDLを自動化する方法が便利 以下の手順でやることが多い openコマンドでcsvファイルをDLできるようにする 1.csvダウンロードのURLを読み解く URLを調べる クラウドツールなどで、csvダウンロードのURLが公開されていることが前提 DLボタンを右クリックでパスをコピーなどでわかる事が多い URLを解析する だいたい以下のような形式が多い https:xxxxxxx{固定URL1}/segmentxx{セグメント}/xxxxxxx{固定URL2}/yyyymmdd{データ抽出開始日}/xxxxxxx{固定URL3}/xx{データの抽出期間} この固定のURLと可変のパラメータを見極める openコマンド用の変数を考える 上記の例でいうと、以下のような変数が考えられる 固定URLの変数 URL変数1=https:xxxxxxx{固定URL1} URL変数2=/xxxxxxx/{固定URL2} URL変数3=/xxxxxxx{固定URL3} 可変パラメーターの変数 セグメント=segmentxx{セグメント} データ抽出開始日=yyyymmdd データの抽出期間=xx{データの抽出期間} この可変パラメーターを自由に変更しつつ、openコマンドで開けるようにする 2.openコマンドで抽出するscript openコマンドの基本的な使い方 #!/bin/bash open "https://qiita.com/" これを、解析したURLの変数を使えるようにする #!/bin/bash # 抽出用の変数 ## 固定URLの変数 URL変数1=https:xxxxxxx{固定URL1} URL変数2=/xxxxxxx/{固定URL2} URL変数3=/xxxxxxx{固定URL3} ## 可変パラメーターの変数 セグメント=segmentxx{セグメント} データ抽出開始日=yyyymmdd データの抽出期間=xx{データの抽出期間} # 抽出用openコマンド open ""$URL変数1""$セグメント""$URL変数2""$データ抽出開始日""$URL変数3""$データの抽出期間"" さらに、引数で可変パラメーターを指定できるようにする #!/bin/bash ######################################### # csvDL用script # 引数 # 1:セグメント # 2:データ抽出開始日(yyyymmdd) # 3:データの抽出期間 # (利用例)sh csv_dl.sh segmentA 2021-7-1 7 ######################################### # 抽出用の変数 ## 固定URLの変数 URL変数1=https:xxxxxxx{固定URL1} URL変数2=/xxxxxxx/{固定URL2} URL変数3=/xxxxxxx{固定URL3} ## 可変パラメーターの変数 セグメント=$1 データ抽出開始日=$2 データの抽出期間=$3 # 抽出用openコマンド open ""$URL変数1""$セグメント""$URL変数2""$データ抽出開始日""$URL変数3""$データの抽出期間"" 3.DLしたファイルの名前を変更して保存するscript csvDL系のファイル名はだいたいわかりにくいので一貫性のあるファイル名に変更する csvDLしたファイルがローカルのdownloadsにおかれる場合を想定 固定のファイル名+セグメント名+データ抽出開始日+データ抽出期間.csvというファイル名にしたい場合 #!/bin/bash cd /Users/DIRNAME/Downloads text=$(ls -t | head -n 1) mv "$text" "ファイル名"$セグメント""$データ抽出開始日""$データの抽出期間".csv" 4.処理を一つにまとめる #!/bin/bash ######################################### # csvDL用script # 引数 # 1:セグメント # 2:データ抽出開始日(yyyymmdd) # 3:データの抽出期間 # (利用例)sh csv_dl.sh segmentA 2021-7-1 7 ######################################### # 抽出用の変数 ## 固定URLの変数 URL変数1=https:xxxxxxx{固定URL1} URL変数2=/xxxxxxx/{固定URL2} URL変数3=/xxxxxxx{固定URL3} ## 可変パラメーターの変数 セグメント=$1 データ抽出開始日=$2 データの抽出期間=$3 # 抽出用openコマンド open ""$URL変数1""$セグメント""$URL変数2""$データ抽出開始日""$URL変数3""$データの抽出期間"" sleep 10 # ファイルを保存するまでスリープさせる # ファイル名を変更して保存 cd /Users/DIRNAME/Downloads text=$(ls -t | head -n 1) mv "$text" "ファイル名"$セグメント""$データ抽出開始日""$データの抽出期間".csv" 作成したscriptを定期実行できる仕組みつくる Automatorなどを利用して定期的に叩く仕組みを作成すれば完了! 以上 ひとこと 絶対もっとよい方法ありそうなのと、書き方も拙いので忌憚なきご意見を 世の中のcsvファイルDLの命名規則を統一化してほしい