Rails id以外でのリクエスト処理

注意
Railsで初めてのまともなものを作ったので、
ベストプラクティスは他にあるかもしれないです
ご存じの方はコメントでご指摘ください

本題
リクエストをid以外のもので出したくてそのやり方について軽くまとめました

ルーティングの設定
routes.rb

Rails.application.routes.draw do
  resources :users, param: :name
end

resources :users の後に param: :指定したいもの
リクエストで指定したいものを記述

次はモデル
user.rb

class User < ApplicationRecord
  def to_param
    name
  end
end

to_param 関数を定義
これはviewで楽するためとか書いている記事を読んだので、
自分はviewが必要ないものだったので定義していなかったのですが、
これがないとエラー吐き出してきたので記述

最後にコントローラ
users_controller.rb

class UsersController < ApplicationController
  def show
    user = User.find(name: params[:name])
  end
end

nameでリクエストをしたかったので、自分はnameになっています
find(params[:name]) と書いている記事があり、最初はそのように書いていただが、
これもエラーを吐かれたので、上述のように書いた

No.1673 Lamps on a line

yukicoder.me


まずは二つのコードを
AC

N,Q = map(int,input().split())
switch = [0]*(N)
ans = 0

for i in range(Q):
    L,R = map(int,input().split())
    for j in range(L-1,R):
        if switch[j] == 0:
            switch[j] = 1
            ans += 1
        else:
            switch[j] = 0
            ans -= 1
    print(ans)


TLE

N,Q = map(int,input().split())
switch = [0]*(N)
for i in range(Q):
    L,R = map(int,input().split())
    for j in range(L-1,R):
        if switch[j] == 0:
            switch[j] = 1
        else:
            switch[j] = 0
    print(switch.count(1))

二つのコードは、1の個数の数え方だけ異なる
変数をインクリメントするか、count()メソッドで数えるか
覚えたてのメソッドってなぜか使いたくなっちゃいますもんね
僕だけかもしれないけど

ただし今回はNの数が増えるにつれて、count()メソッドがネックになっています
count()は中身をすべて確認し、該当する要素数を出力してくれるので、
Nが大きくなればなるほど、計算量が増えます
なので今回は、0を1にするタイミングで変数にインクリメントして実装

※ count()メソッドは文字列にも使うことができるので、
  厳密に言うと要素数を出力という説明は不自然かもしれませんが、
  わかりやすく説明するために、そのような表現を使わせていただきました

Permission denied (publickey) について

鍵に独自の名前を付けて保存した場合に限り下記が必要

今回はGithub用に作成した際に起きたのでそのような名前です

Host github github.com
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_github #付けた名前にする
    User git


こんな単純で初歩的なことではあるのですが、
意外と鍵作成の解説とかにこのこと載ってなかったりするんですよね
なので誰かのお役に立てればと

Python3ではTLEなのにPyPy3だと通った話

atcoder.jp

アルゴリズムと数学』の4.1-2の演習問題でそれは起きました
「034 - Nearest Points」

注意
文中のPythonは処理系のCPythonのことを指しています
言語のPythonを指す際は、Python言語と記載しています


問題の起きたコード

N = int(input())
X,Y = [None]*N,[None]*N
for i in range(N):
    X[i],Y[i] = map(int,input().split())
    
Answer = 10**6
for i in range(N-1):
    for j in range(i+1,N):
        Answer = min(Answer, ((X[i]-X[j])**2 + (Y[i]-Y[j])**2)**0.5)

print(Answer)


演習問題の制約にO(N2)まではOK!と書いてあるのに、
何度提出してもTLE,TLE,,,TLEって何が違うのか全く分からないまま仕方なく、
他の方のACコードを拝見しても、自分のコードと計算量が同じものも多々あり尚更困惑

PythonでTLEのコードがPyPyだと通ることもあるという、以前どこかで見た記事を思い出し、
PyPyで提出したらお見事ACで無事通過!!

Nが106以上からPyPyのほうが実行時間が短くなり、Nが増えるにつれてその違いも顕著になっています
ただし、105以下の時は僕が調べた限りPyPyよりPythonのほうが実行時間が短かったです
※ 調査方法が単純なものなため、間違っていたら大変申し訳ないです
https://atcoder.jp/contests/math-and-algorithm/custom_test ← ここでfor文使って試した

注意
PyPyでWAなのに、PythonだとACで通ったりということもあるらしいので、
競技プログラミングPython言語を使う方は過去問などで経験を積んで使い分けが必要かも
※ コンテスト中はWA取るとペナルティがあるため

yukicoder No.1644 Eight Digits

yukicoder.me
解答

from itertools import permutations

K = int(input())
N = permutations('12345678',8)
cnt = 0

for i in N:
    if int(''.join(list(i))) % K == 0:
        cnt += 1
print(cnt)


permutations('****', N)

これは第一引数の文字列をN個並べてできる順列を返してくれる
※ Permutation : 順列

# こんな感じ
a = permutations('123',3)
for i in a:
    print(i)

=> ('1', '2', '3')
   ('1', '3', '2')
   ('2', '1', '3')
   ('2', '3', '1')
   ('3', '1', '2')
   ('3', '2', '1')



解き方&個人的苦労
今回の問題では8! = 40320個なので、普通に繰り返しでKの倍数を数えて計算量は問題ない
個人的にはpermutations がtuple で返してくるのでそれをどう処理するかと、
Pythonにpermutationsというものがあるということに気づくまでが時間かかった

DeprecationWarning: find_element_by_class_name is deprecated.について

内容
タイトルからわかりづらく失礼しました
O'reilly社の『退屈なことはPythonにやらせよう』を読んでいて、
なにかとSeleniumのところでつまづく

理由としては本ではバージョンが3なのに対して、 自分が使っているバージョンがSelenium4なため
なのでいちいち躓きたくない人はSeleniumをインストールする際はバージョン指定してするといいかも

本題
タイトルの警告は、
下記ソース内のこの部分を変更してくださいねーというお知らせ

変更前
try:
    elem = browser.find_element_by_class_name('bookcover')

おそらくバージョン4になってから変更があったみたいで記述方法が下記の様に変わった

変更後
from selenium.webdriver.common.by import By

try:
    elem = browser.find_element(by=By.CLASS_NAME,value='bookcover')
もしくは
try:
    elem = browser.find_element(By.CLASS_NAME, 'bookcover')


詳しくはこちら参考に

stackoverflow.com

WSL2でSleniumモジュールを使う

O'reilly社の『退屈なことはPythonにやらせよう』の11章でSeleniumを使うのですが
初っ端つまづいたのでその解決方法

環境
WSL2
Python 3.8.10
Ubuntu-20.04
selenium 4.1.3

from selenium import webdriver
browser = webdriver.Firefox()
以下省略

上記をPythonシェルで実行していくのだが、
指示通りgeckodriverもダウンロードして実行ファイルも配置していたのにエラー

github.com geckodriverは~.tar.gzをダウンロード
Windowsのダウンロード先からWSLの実行元へ移動

tar -xvf filename.tar.gz
chmod +x geckodriver

tarコマンドで解凍後、chmodコマンドで実行権限付与
したのにも関わらず、エラーの連続


ちなみにWSLにFirefoxをインストールしていないならすること

sudo apt install firefox

起動

firefox

起動せずにエラーが出る場合はVcXsrvが入っていないケースが多い
下の解決方法を実施の後、もう一度試してみる

解決した方法

VcXsrvをダウンロードし、環境を設定したら無事にエラー解消されました
VcXsrvとはWSL上のLinuxGUIアプリケーションを実行可能にしてくれます
VcXsrvの設定は下記のサイトを

dev.classmethod.jp