Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

asdfでpython3.11.5がインストールできない

intel Macasdfを使ってpython 3.11.5がインストールできなかった問題を対処した。

現象としては asdf list-all python に対応するバージョンが出てこない。

やったこと brewのupdate asdfを一端アンインストールし、 brew install asdfで入れ直した。

セレクタの練習

htmlを

<html>
    <head>
    <link rel="stylesheet" href="sample.css"/>
    </head>
    <body>
        <div class="root"> 根っこ
            <div class="sub">
                根っこの子供
                 <div class="subsub">  
                     根っこの子供の子供
                 </div>
                 <div class="poge">  
                    根っこの子供の子供2
                </div>
            </div>
            <div class="poi">  
                根っこの子供2
            </div>
            <div class="poi2">  
                根っこの子供3
            </div>
        </div>
        <div class="tonari">
            根っこの隣
        </div>
    </body>
</html>

とする。

cssとして

.root {
    background-color: red;
    padding: 30px;
}

.root > div {
    padding: 0px 50px;
}

.root > div > div {
    background-color: indigo;
}

div:not([class*="sub"]) {
    font-size: 50px;
}

div[class*="sub"] {
    font-size: 5px;
}

.sub::first-line {
    color: yellow;
}

.poge::after {
    content: "!";
    color: plum;
}
div:nth-child(3) {
    color: purple;
    background-color: greenyellow;
}

などが使える。ダサいページができる。

f:id:KatagiriSo:20211213173857p:plain
結果

spyonのimport

同一ファイル内にある

function funcA() : B { return funcB()} 
function funcB() : B { ... }

においてfuncBをモックにしてfuncAを呼んでもモックが呼ばれない。

import  * as thisModule from "./funcA"
function funcA() : B { return thisModule.funcB()} 
function funcB() : B { ... }

とすると呼ばれる。つらい。

値を消す

function removeValueSubOrder<T, K extends keyof T, P extends keyof T[K]>(
  target: T,
  subOrder: K,
  keys: P[]
): T {
  const obj = { ...target } as any
  for (const key of keys) {
    obj[subOrder][key] = undefined
  }
  return obj as T
}

function removeValue<T, K extends keyof T>(target: T, keys: K[]): T {
  const obj = { ...target } as any
  for (const key of keys) {
    obj[key] = undefined
  }
  return obj as T
}

Gridを独自コンポーネントにする

(props) => react.componentにするだけで使えるようになる。

const useStyles = (theme: Theme) => {
    return makeStyles({
        root: {
            flexGrow: 1
        },
        paper: {
            padding: theme.spacing(2),
            textAlign: 'center',
            color: theme.palette.text.secondary

        }
    })
}


const Conainer = (props:any) => <Grid container {...props}/>
const Item = (props:any) => <Grid item {...props}/>



const UnderStandingBreakpoints2 = () => {
    const theme = useTheme()
    const classes = useStyles(theme)()
    return (
        <div className={classes.root}>
            <Conainer spacing={4}>
                <Item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Item>
                <Item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Item>
                <Item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Item>
                <Item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Item>
            </Conainer>
        </div>
    )
};

export default UnderStandingBreakpoints2

Gridにスタイルをあてる

makeStylesを使う。

const useStyles = (theme:Theme) => {
    return makeStyles({
        root: {
            flexGrow: 1
        },
        paper: {
            padding: theme.spacing(2),
            textAlign: 'center',
            color: theme.palette.text.secondary

        }
    })
}

これをuseStyleしてやればよいだけ。

const UnderStandingBreakpoints = () => {
    const theme = useTheme()
    const classes = useStyles(theme)()
    return (
        <div className={classes.root}>
            <Grid container spacing={4}>
                <Grid item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Grid>
                <Grid item xs={12} sm={6} md={3}>
                    <Paper className={classes.paper}>
                        xs = 12 sm = 6 md = 3
                    </Paper>
                </Grid>
            </Grid>
        </div>
    )
};

export default UnderStandingBreakpoints

サイズは

xs>0px sm>=600px md>=960px lg>1280px xl>1920px

で適応される。画面全体は12分割されそのうちどのわりあいになるかを指定している。

構造体を文字列としてみる

struct Hoge {
 let name:String
 let age:Int
}

extension String.StringInterpolation {
mutationg func appendInterpolation(_ value: User) {
  appendInterpolation("Hoge's name is \(value.name) and he name is \(value.age)")
 }
}

としておいて、

let hoge = Hoge(name:"poi", age:44)
print("Hoge deatil \(hoge)) /// ここでhogeを引数にとっていることがポイント

これはCustomStringConvertibleと同じである。

しかし、こんなこともできる・

引数を好きなだけとれるのだ

extension String.StringIterpolation {
mutating func appendInterpolation(_ number: Int, style:NumberFormatter.Style) {
 formatter.numberStyle = style
 if let result = formatter.string(from: number as NSNumber) {
  appendLiteral(result)
 }
}

これで $20とか、1st, 12thとかできる。

let number = Int.random(in:0...100)
let lucky = "lucky number this weeks os \(number, style: .spellOut)."
print(lucky)

appendLiteralは必要に応じて何度も呼べる。

extension String.StringInterpolation {
mutating func appendInterpolation(repeat str: string, _ count:Int) {
 for _ in 0..< count {
  appendLiteral(str)
  }
 }
}
print("say, \(repat: "hello!,", 3)

他のSwiftの機能と組み合わせて例えば配列がないときはデフォルト表示するなどできる。

extension String.StringInterpolation {
 mutating func appendInterpolation(_ value:[String], empty defaultValue:@autoclosure () -> String) {
  if value.count == 0
     appendLiteral(defaultValue())
  } else {
    appendLiteral(values.joined(separator:","))
  }
 }
}

let particle = ["fermion", "boson"]
print("List of particle: \(names, empty: "No one").")

@autoclosureを使うことで単純なあたいや、複雑な関数を呼び出しできる。

ExpressibleByStringLiteralやExpressibleByStringInterpolationなどと組み合わせることで
文字列補間で全体の型を作れるようになり、CustomStringConvertibleを通してその型をprintできるようにさえなった。

必要なことは
ExpressibleByStringLiteralとExpressibleByStringInterpolationに準拠することで必要ならCustomStringConvertibleにも準拠すること。
自分の型の中にネストしてStringInterpolation構造体を作りStringInterpolationProtocolに準拠させる。その初期化には期待する大まかなデータ量を入れる必要がある。また、appendLiteral() を実装する必要がある。appendInterpolation()もいる。
初期化も2ついる。

様々な共通エレメントからHTMLを構成する型を例につくろう。

struct HTMLComponent: ExpressibleByStringLiteral, ExpressibleByStringInterpolation, CustomStringConvertible { struct StringInterpolation: StringInterpolationProtocol { // start with an empty string var output = ""

    // allocate enough space to hold twice the amount of literal text
    init(literalCapacity: Int, interpolationCount: Int) {
        output.reserveCapacity(literalCapacity * 2)
    }

    // a hard-coded piece of text – just add it
    mutating func appendLiteral(_ literal: String) {
        print("Appending \(literal)")
        output.append(literal)
    }

    // a Twitter username – add it as a link
    mutating func appendInterpolation(twitter: String) {
        print("Appending \(twitter)")
        output.append("<a href=\"https://twitter/\(twitter)\">@\(twitter)</a>")
    }

    // an email address – add it using mailto
    mutating func appendInterpolation(email: String) {
        print("Appending \(email)")
        output.append("<a href=\"mailto:\(email)\">\(email)</a>")
    }
}

// the finished text for this whole component
let description: String

// create an instance from a literal string
init(stringLiteral value: String) {
    description = value
}

// create an instance from an interpolated string
init(stringInterpolation: StringInterpolation) {
    description = stringInterpolation.output
}

}




let text: HTMLComponent = "You should follow me on Twitter (twitter: "twostraws"), or you can email me at (email: "paul@hackingwithswift.com")." print(text) /// You should follow me on Twitter @twostraws, or you can email me at paul@hackingwithswift.com.

これでHTMLが吐き出されるが、他にも使い方がありそう。

参考文献

[https://github.com/twostraws/whats-new-in-swift-5-0:title]