问:
Any way to write my protocol without using generics, or otherwise workaround using associated types?
I have a protocol ScaleDetails, and I want several different Scale structs to conform (i.e. MajorScale, DiminishedScale, etc.). Then I want to have a different protocol, ComboChord, which has a variable scale of type ScaleDetails, which would be a different scale depending on another variable elsewhere. The problem is I can't assign my scale var in ComboChord to type ScaleDetails because I can't figure out how to write my protocol without using associated types.

Each different scale uses a different Mode enum (e.g. Mode.SevenDeg for MajorScale and Mode.TwoDeg for DiminishedScale). And each scale has functions that return an instance or instances of that specific scale struct. So I don't see a way forward without using generics in my ScaleDetails protocol. I'm trying to write this without using classes if possible but I'm willing to use them if necessary. I'm also really trying to avoid typecasting for my scales because I don't want to have to list each scale possibility every time I call it. How can I fix this?

ScaleDetails Protocol

```<code>protocol ScaleDetails {
    associatedtype ScaleMode where ScaleMode: RawRepresentable
    associatedtype T
    //...
    var root: Root { get set }
    var mode: ScaleMode { get set }
    //...
    init(_ root: KeyName.Root, mode: ScaleMode)

    func translated(by offset: Int) -> T

    func enharmSwapped() -> T
    //...
    mutating func switchMode(mode: ScaleMode)

    func getParallelModes(root: KeyName.Root) -> [T]
    func getParentModes() -> [T]
}
</code>```

ComboChord Protocol

```<code>protocol ComboChord {
    var scale: ScaleDetails // doesn't work

    static var validCombos: [[Int]] { get }

    var quality: Suffix { get }
    var uprStrNotes: [Int] { get }
/*
error: "Protocol can only be used as a generic constraint
because it has Self or associatedType requirements"
*/
}
</code>```

Mode enums

```<code>enum Mode {

    enum TwoDeg: Int, CaseIterable, ModeProtocol {
        case one = 0, two

        //...
    }

    enum SevenDeg: Int, CaseIterable, ModeProtocol {
        case one = 0, two, three, four, five, six, seven

        //...
    }
}
</code>```

Major Scale

```<code>struct MajorScale: ScaleDetails {
    var root: Root
    var mode: Mode.SevenDeg

    //...

    init(_ root: KeyName.Root, mode: Mode.SevenDeg = .one) {
        self.root = Root(root)
        self.mode = mode
        self.enharm = root.r.enharm
    }

    func translated(by offset: Int) -> MajorScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    //...
    mutating func switchMode(mode: Mode.SevenDeg) {
        self.mode = mode
    }

    //...

    func enharmSwapped() -> MajorScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    func getParallelModes(root: KeyName.Root) -> [MajorScale] {
        return Mode.SevenDeg.allCases.map {MajorScale(root, mode: $0)}
    }

    func getParentModes() -> [MajorScale] {
        //...code to get array of scales
        return parentModes
    }
}
</code>```

DiminishedScale

```<code>struct DiminishedScale: ScaleDetails {
    var root: Root
    var mode: Mode.TwoDeg

    //...

    init(_ root: KeyName.Root, mode: Mode.TwoDeg = .one) {
        self.root = Root(root)
        self.mode = mode
        self.enharm = root.r.enharm
    }

    func translated(by offset: Int) -> DiminishedScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    //...
    mutating func switchMode(mode: Mode.TwoDeg) {
        self.mode = mode
    }

    //...

    func enharmSwapped() -> DiminishedScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    func getParallelModes(root: KeyName.Root) -> [DiminishedScale] {
        return Mode.TwoDeg.allCases.map {DiminishedScale(root, mode: $0)}
    }

    func getParentModes() -> [DiminishedScale] {
        //...code to get array of scales
        return parentModes
    }
}
</code>```

KeyName.Root

```<code>enum KeyName: String, CaseIterable {
    case c = "C"
    case d = "D"
    case e = "E"
    case f = "F"
    case g = "G"
    case a = "A"
    case b = "B"

    case cB = "C\u{266D}"
    case dB = "D\u{266D}"
    case eB = "E\u{266D}"
    case fB = "F\u{266D}"
    case gB = "G\u{266D}"
    case aB = "A\u{266D}"
    case bB = "B\u{266D}"

    case cSh = "C\u{266F}"
    case dSh = "D\u{266F}"
    case eSh = "E\u{266F}"
    case fSh = "F\u{266F}"
    case gSh = "G\u{266F}"
    case aSh = "A\u{266F}"
    case bSh = "B\u{266F}"

    case c_bb = "C\u{266D}\u{266D}"
    case d_bb = "D\u{266D}\u{266D}"
    case e_bb = "E\u{266D}\u{266D}"
    case f_bb = "F\u{266D}\u{266D}"
    case g_bb = "G\u{266D}\u{266D}"
    case a_bb = "A\u{266D}\u{266D}"
    case b_bb = "B\u{266D}\u{266D}"

    case cX = "Cx"
    case dX = "Dx"
    case eX = "Ex"
    case fX = "Fx"
    case gX = "Gx"
    case aX = "Ax"
    case bX = "Bx"

    enum Root {
        case c, d, e, f, g, a, b
        case cB, dB, eB, fB, gB, aB, bB
        case cSh, dSh, eSh, fSh, gSh, aSh, bSh

        var r: KeyName {
            switch self {
            case .c:
                return .c
            case .d:
                return .d
            case .e:
                return .e
            case .f:
                return .f
            case .g:
                return .g
            case .a:
                return .a
            case .b:
                return .b
            case .cB:
                return .cB
            case .dB:
                return .dB
            case .eB:
                return .eB
            case .fB:
                return .fB
            case .gB:
                return .gB
            case .aB:
                return .aB
            case .bB:
                return .bB
            case .cSh:
                return .cSh
            case .dSh:
                return .dSh
            case .eSh:
                return .eSh
            case .fSh:
                return .fSh
            case .gSh:
                return .gSh
            case .aSh:
                return .aSh
            case .bSh:
                return .bSh
            }
        }

        init(_ key: KeyName) {
            switch key {
            case .c:
                self = .c
            case .d:
                self = .d
            case .e:
                self = .e
            case .f:
                self = .f
            case .g:
                self = .g
            case .a:
                self = .a
            case .b:
                self = .b
            case .cB:
                self = .cB
            case .dB:
                self = .dB
            case .eB:
                self = .eB
            case .fB:
                self = .fB
            case .gB:
                self = .gB
            case .aB:
                self = .aB
            case .bB:
                self = .bB
            case .cSh:
                self = .cSh
            case .dSh:
                self = .dSh
            case .eSh:
                self = .eSh
            case .fSh:
                self = .fSh
            case .gSh:
                self = .gSh
            case .aSh:
                self = .aSh
            case .bSh:
                self = .bSh
            default:
                self = .c
            }
        }
    }
    //...
}
</code>```

Root

```<code>struct Root: Note {
    var noteName: String {
        return key.name
    }

    var rootKey: KeyName.Root
    var noteNum: NoteNum
    var num: Int {return noteNum.num}
    var enharm: Enharmonic

    var degName: (name: DegName.Name, short: DegName.Short, long: DegName.Long) {
        return (name: DegName.Name(.root), short: DegName.Short(.root), long: DegName.Long(.root))
    }

    var key: KeyName

    init(noteNum: NoteNum = .zero, enharm: Enharmonic = .flat) {
        self.noteNum = noteNum
        self.enharm = enharm

        var ks: KeySwitch {
            return KeySwitch(enharm: enharm)
        }

        var rs: RootSwitch {
            return RootSwitch(enharm: enharm)
        }

        switch noteNum {
        case .zero:
            self.key = ks.pickKey(.c, .bSh)
            self.rootKey = rs.pickRoot(.c, .bSh)
        case .one:
            self.key = ks.pickKey(.dB, .cSh)
            self.rootKey = rs.pickRoot(.dB, .cSh)
        case .two:
            self.key = .d
            self.rootKey = .d
        case .three:
            self.key = ks.pickKey(.eB, .dSh)
            self.rootKey = rs.pickRoot(.eB, .dSh)
        case .four:
            self.key = ks.pickKey(.fB, .e)
            self.rootKey = rs.pickRoot(.fB, .e)
        case .five:
            self.key = ks.pickKey(.f, .eSh)
            self.rootKey = rs.pickRoot(.f, .eSh)
        case .six:
            self.key = ks.pickKey(.gB, .fSh)
            self.rootKey = rs.pickRoot(.gB, .fSh)
        case .seven:
            self.key = .g
            self.rootKey = .g
        case .eight:
            self.key = ks.pickKey(.aB, .gSh)
            self.rootKey = rs.pickRoot(.aB, .gSh)
        case .nine:
            self.key = .a
            self.rootKey = .a
        case .ten:
            self.key = ks.pickKey(.bB, .aSh)
            self.rootKey = rs.pickRoot(.bB, .aSh)
        case .eleven:
            self.key = ks.pickKey(.cB, .b)
            self.rootKey = rs.pickRoot(.cB, .b)
        }
    }

    init(_ key: KeyName.Root) {
        self.key = key.r
        self.rootKey = key
        self.noteNum = self.key.noteNum
        self.enharm = self.key.enharm
    }

    mutating func kSW(ks: KeySwitch) {
        switch noteNum {
        case .zero:
            self.key = ks.pickKey(.c, .bSh)
        case .one:
            self.key = ks.pickKey(.dB, .cSh)
        case .two:
            self.key = .d
        case .three:
            self.key = ks.pickKey(.eB, .dSh)
        case .four:
            self.key = ks.pickKey(.fB, .e)
        case .five:
            self.key = ks.pickKey(.f, .eSh)
        case .six:
            self.key = ks.pickKey(.gB, .fSh)
        case .seven:
            self.key = .g
        case .eight:
            self.key = ks.pickKey(.aB, .gSh)
        case .nine:
            self.key = .a
        case .ten:
            self.key = ks.pickKey(.bB, .aSh)
        case .eleven:
            self.key = ks.pickKey(.cB, .b)
        }
    }

    mutating func swapEnharm() {
        enharm = enharm == .flat ? .sharp : .flat
        kSW(ks: KeySwitch(enharm: enharm))
        rootKey = KeyName.Root(key)
    }

    func enharmSwapped() -> Root {
        return Root(noteNum: noteNum, enharm: enharm == .flat ? .sharp : .flat)
    }
}
</code>```

DetailChord

(heavily pared down for length...original is about 1400 lines)

```<code>struct DetailChord {
    enum DCType {
        case dom7, ma7, mi7, mi7b5, dim7, error
    }

    init(resultChord: ResultChord?, verdict: Verdict = .goodToGo) {
        self.verdict = verdict
        self.dRC = resultChord
        if let rc = dRC {
            switch rc.baseChord.lowerQual {
            case .dom7:
                dct = .dom7
            case .ma7:
                dct = .ma7
            case .mi7:
                dct = .mi7
            case .mi7_b5:
                dct = .mi7b5
            case .dim7:
                dct = .dim7
            }
        } else {
            dct = .error
        }
    }

    var dct: DCType

    var dRC: ResultChord?

    var verdict: Verdict

    var validCombos: [[[Int]]] {
        switch dct {
        case .dom7:
            return Dom7.validCombos
        case .ma7:
            return Maj7.validCombos
        case .mi7:
            return Min7.validCombos
        case .mi7b5:
            return Min7_b5.validCombos
        case .dim7:
            return Dim7.validCombos
        default:
            return [[[]]]
        }
    }

    var tension: [[Int]] {
        switch dct {
        case .dom7:
            return Dom7.tension
        case .ma7:
            return Maj7.tension
        case .mi7:
            return Min7.tension
        case .mi7b5:
            return Min7_b5.tension
        case .dim7:
            return Dim7.tension
        default:
            return [[]]
        }
    }

    func qualSwitcher(validCombos: [[[Int]]], degrees: [Int]) -> Int {
        var validCombosIndex = Int()
        for (index, combos) in validCombos.enumerated() {
            if combos.contains(degrees) {
                validCombosIndex = index
                break
            }
        }

        return validCombosIndex
    }

    var chord: ComboChord {
        mutating get {
            if let rc = dRC {
                let degrees = rc.degrees
                let degreesUnsorted = rc.degreesUnsorted
                let baseChord = rc.baseChord
                let degSet = rc.degSet

                var validCombosIndex = Int()

                func tensionOrGoodToGo(getComboChord: GetComboChord) -> ComboChord {
                    if !tension.contains(degrees) { // good to go!
                        verdict = .goodToGo
                        validCombosIndex = qualSwitcher(validCombos: validCombos, degrees: degrees)
                        return getComboChord(degSet, validCombosIndex)
                    } else { // tension!
                        verdict = .tension
                        if let tensionQual = rc.baseChord.qualSuffix as? Suffix.Lower {
                            return TensionChord(tensionQual, rc.degreesUnsorted)
                        } else {
                            return ErrorChord()
                        }
                    }
                }

                switch dct {
                case .dom7:
                    return tensionOrGoodToGo(getComboChord: Dom7.getComboChord(degSet:validCombosIndex:))
                case .ma7:
                    return tensionOrGoodToGo(getComboChord: Maj7.getComboChord(degSet:validCombosIndex:))
                case .mi7:
                    return tensionOrGoodToGo(getComboChord: Min7.getComboChord(degSet:validCombosIndex:))
                case .mi7b5:
                    return tensionOrGoodToGo(getComboChord: Min7_b5.getComboChord(degSet:validCombosIndex:))
                case .dim7:
                    return tensionOrGoodToGo(getComboChord: Dim7.getComboChord(degSet:validCombosIndex:))
                case .error:
                    return ErrorChord()
                }
            } else {
                print("rc not found!")
                dct = .error
                return ErrorChord()
            }
        }
    }

    struct Dom7: DetailChordType {
        static let matches = Mixolydian.validCombos + LydianDom.validCombos + HalfWholeDim.validCombos + AltP5.validCombos + MelodicMinor_Chord.validCombos + HexatonicSh9Sh11_Chord.validCombos + HalfWholeDimFlat13_Chord.validCombos

        static let validCombos: [[[Int]]] = [Mixolydian.validCombos, LydianDom.validCombos, HalfWholeDim.validCombos, AltP5.validCombos, MelodicMinor_Chord.validCombos, HexatonicSh9Sh11_Chord.validCombos, HalfWholeDimFlat13_Chord.validCombos]

        static let tension = [[0, 1, 4, 5, 7, 8, 10], [0, 4, 7, 8, 10, 11], [0, 4, 5, 7, 9, 10], [0, 2, 4, 7, 10, 11], [0, 2, 4, 5, 7, 10], [0, 3, 4, 6, 7, 10, 11], [0, 2, 4, 5, 7, 9, 10], [0, 4, 7, 10, 11], [0, 4, 5, 7, 8, 10], [0, 3, 4, 7, 8, 10, 11], [0, 1, 4, 5, 7, 10], [0, 2, 4, 6, 7, 10, 11], [0, 1, 4, 5, 7, 9, 10], [0, 3, 4, 7, 10, 11], [0, 2, 4, 5, 7, 8, 10], [0, 4, 5, 7, 8, 10, 11], [0, 2, 4, 7, 8, 10, 11], [0, 2, 4, 5, 7, 10, 11], [0, 3, 4, 5, 7, 10], [0, 4, 5, 7, 10], [0, 4, 6, 7, 10, 11], [0, 4, 7, 9, 10, 11], [0, 1, 4, 6, 7, 10, 11]]

        static let tensionTones = [5, 11]

        static func getComboChord(degSet: Set<Int>, validCombosIndex: Int) -> ComboChord {
            switch validCombosIndex {
            case 0: // mixolydian
                switch degSet {
                case let degs where degs.isSuperset(of: Dom7.Mixolydian.XIII.uprStrNotes): // 13
                    return Dom7.Mixolydian.xiii
                // sus4/sus2 on 2nd, sus2 on 5th, min or sus 4 triad on maj6
                case let degs where degs.isSuperset(of: Dom7.Mixolydian.Nine.uprStrNotes): // 9
                    // sus2 on root, min or sus4 triad on p5
                    return Dom7.Mixolydian.nine
                default: // 7
                    //maj triad on root, dim triad on 3rd
                    return Dom7.Mixolydian.seven
                }
            case 1: // lydian dominant
                // similar structure to case 0
            case 2: // half-whole dim
                // similar structure to case 0
            case 3:
            // similar structure to case 0
            case 4: // 5th mode melodic minor
                // similar structure to case 0
            case 5: // hexatonicSh9Sh11
            // similar structure to case 0
            default: // half-whole dim(b13)
                // similar structure to case 0
            }
        }

        var chordType: ComboChord = Mixolydian.seven

        enum Mixolydian: ComboChord {

            case seven, nine, xiii

            var scale: ScaleDetails {
                switch self {
                default:
                    return Major(mode: .five, modeOffset: 0)
                }
            }

            static let validCombos: [[Int]] = Seven.validCombos + Nine.validCombos + XIII.validCombos

            struct Seven {
                static let validCombos = [[0, 4, 7, 10]]
                static let uprStrNotes: [Int] = []
            }

            struct Nine {
                static let validCombos: [[Int]] = [[0, 2, 4, 7, 10]]
                static let uprStrNotes: [Int] = [2]
            }

            struct XIII {
                static let validCombos: [[Int]] = [[0, 2, 4, 7, 9, 10], [0, 4, 7, 9, 10]]
                static let uprStrNotes: [Int] = [9]
            }

            var quality: Suffix  {
                switch self {
                case .seven:
                    return .sev
                case .nine:
                    return .nine
                case .xiii:
                    return .xiii
                }
            }

            var uprStrNotes: [Int] {
                switch self {
                case .seven:
                    return Seven.uprStrNotes
                case .nine:
                    return Nine.uprStrNotes
                case .xiii:
                    return XIII.uprStrNotes
                }
            }
        }

        enum LydianDom: ComboChord {
            // same structure as Mixolydian
        }

        enum HalfWholeDim: ComboChord {
            // same structure as Mixolydian
        }

        enum AltP5: ComboChord {
            // same structure as Mixolydian
        }

        enum HexatonicSh9Sh11_Chord: ComboChord {
            // same structure as Mixolydian
        }

        enum MelodicMinor_Chord: ComboChord {
            // same structure as Mixolydian
        }

        enum HalfWholeDimFlat13_Chord: ComboChord {
            // same structure as Mixolydian
        }
    }

    struct Maj7: DetailChordType {
        // same structure as Dom7
    }

    struct Min7: DetailChordType {
        // same structure as Dom7
    }

    struct Min7_b5: DetailChordType {
        // same structure as Dom7
    }

    struct Dim7: DetailChordType {
        // same structure as Dom7
    }
}
</code>```

答:
Not sure if it will fit your usage, but maybe you can make ComboChord generic as well

```<code>protocol ComboChord {
    associatedtype Scale: ScaleDetails
    var scale: Scale { get }
}
</code>```

And then use it like this

```<code>struct Chord: ComboChord {

    var scale: DiminishedScale

}
</code>```

Body:
I have a protocol ScaleDetails, and I want several different Scale structs to conform (i.e. MajorScale, DiminishedScale, etc.). Then I want to have a different protocol, ComboChord, which has a variable scale of type ScaleDetails, which would be a different scale depending on another variable elsewhere. The problem is I can't assign my scale var in ComboChord to type ScaleDetails because I can't figure out how to write my protocol without using associated types.

Each different scale uses a different Mode enum (e.g. Mode.SevenDeg for MajorScale and Mode.TwoDeg for DiminishedScale). And each scale has functions that return an instance or instances of that specific scale struct. So I don't see a way forward without using generics in my ScaleDetails protocol. I'm trying to write this without using classes if possible but I'm willing to use them if necessary. I'm also really trying to avoid typecasting for my scales because I don't want to have to list each scale possibility every time I call it. How can I fix this?

ScaleDetails Protocol

protocol ScaleDetails {
    associatedtype ScaleMode where ScaleMode: RawRepresentable
    associatedtype T
    //...
    var root: Root { get set }
    var mode: ScaleMode { get set }
    //...
    init(_ root: KeyName.Root, mode: ScaleMode)

    func translated(by offset: Int) -> T

    func enharmSwapped() -> T
    //...
    mutating func switchMode(mode: ScaleMode)

    func getParallelModes(root: KeyName.Root) -> [T]
    func getParentModes() -> [T]
}

ComboChord Protocol

protocol ComboChord {
    var scale: ScaleDetails // doesn't work

    static var validCombos: [[Int]] { get }

    var quality: Suffix { get }
    var uprStrNotes: [Int] { get }
/*
error: "Protocol can only be used as a generic constraint
because it has Self or associatedType requirements"
*/
}

Mode enums

enum Mode {

    enum TwoDeg: Int, CaseIterable, ModeProtocol {
        case one = 0, two

        //...
    }

    enum SevenDeg: Int, CaseIterable, ModeProtocol {
        case one = 0, two, three, four, five, six, seven

        //...
    }
}

Major Scale

struct MajorScale: ScaleDetails {
    var root: Root
    var mode: Mode.SevenDeg

    //...

    init(_ root: KeyName.Root, mode: Mode.SevenDeg = .one) {
        self.root = Root(root)
        self.mode = mode
        self.enharm = root.r.enharm
    }

    func translated(by offset: Int) -> MajorScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    //...
    mutating func switchMode(mode: Mode.SevenDeg) {
        self.mode = mode
    }

    //...

    func enharmSwapped() -> MajorScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    func getParallelModes(root: KeyName.Root) -> [MajorScale] {
        return Mode.SevenDeg.allCases.map {MajorScale(root, mode: $0)}
    }

    func getParentModes() -> [MajorScale] {
        //...code to get array of scales
        return parentModes
    }
}

DiminishedScale

struct DiminishedScale: ScaleDetails {
    var root: Root
    var mode: Mode.TwoDeg

    //...

    init(_ root: KeyName.Root, mode: Mode.TwoDeg = .one) {
        self.root = Root(root)
        self.mode = mode
        self.enharm = root.r.enharm
    }

    func translated(by offset: Int) -> DiminishedScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    //...
    mutating func switchMode(mode: Mode.TwoDeg) {
        self.mode = mode
    }

    //...

    func enharmSwapped() -> DiminishedScale {
        //...do things to the scale

        return MajorScale(newRootKey, mode: mode)
    }

    func getParallelModes(root: KeyName.Root) -> [DiminishedScale] {
        return Mode.TwoDeg.allCases.map {DiminishedScale(root, mode: $0)}
    }

    func getParentModes() -> [DiminishedScale] {
        //...code to get array of scales
        return parentModes
    }
}

KeyName.Root

enum KeyName: String, CaseIterable {
    case c = "C"
    case d = "D"
    case e = "E"
    case f = "F"
    case g = "G"
    case a = "A"
    case b = "B"

    case cB = "C\u{266D}"
    case dB = "D\u{266D}"
    case eB = "E\u{266D}"
    case fB = "F\u{266D}"
    case gB = "G\u{266D}"
    case aB = "A\u{266D}"
    case bB = "B\u{266D}"

    case cSh = "C\u{266F}"
    case dSh = "D\u{266F}"
    case eSh = "E\u{266F}"
    case fSh = "F\u{266F}"
    case gSh = "G\u{266F}"
    case aSh = "A\u{266F}"
    case bSh = "B\u{266F}"

    case c_bb = "C\u{266D}\u{266D}"
    case d_bb = "D\u{266D}\u{266D}"
    case e_bb = "E\u{266D}\u{266D}"
    case f_bb = "F\u{266D}\u{266D}"
    case g_bb = "G\u{266D}\u{266D}"
    case a_bb = "A\u{266D}\u{266D}"
    case b_bb = "B\u{266D}\u{266D}"

    case cX = "Cx"
    case dX = "Dx"
    case eX = "Ex"
    case fX = "Fx"
    case gX = "Gx"
    case aX = "Ax"
    case bX = "Bx"

    enum Root {
        case c, d, e, f, g, a, b
        case cB, dB, eB, fB, gB, aB, bB
        case cSh, dSh, eSh, fSh, gSh, aSh, bSh

        var r: KeyName {
            switch self {
            case .c:
                return .c
            case .d:
                return .d
            case .e:
                return .e
            case .f:
                return .f
            case .g:
                return .g
            case .a:
                return .a
            case .b:
                return .b
            case .cB:
                return .cB
            case .dB:
                return .dB
            case .eB:
                return .eB
            case .fB:
                return .fB
            case .gB:
                return .gB
            case .aB:
                return .aB
            case .bB:
                return .bB
            case .cSh:
                return .cSh
            case .dSh:
                return .dSh
            case .eSh:
                return .eSh
            case .fSh:
                return .fSh
            case .gSh:
                return .gSh
            case .aSh:
                return .aSh
            case .bSh:
                return .bSh
            }
        }

        init(_ key: KeyName) {
            switch key {
            case .c:
                self = .c
            case .d:
                self = .d
            case .e:
                self = .e
            case .f:
                self = .f
            case .g:
                self = .g
            case .a:
                self = .a
            case .b:
                self = .b
            case .cB:
                self = .cB
            case .dB:
                self = .dB
            case .eB:
                self = .eB
            case .fB:
                self = .fB
            case .gB:
                self = .gB
            case .aB:
                self = .aB
            case .bB:
                self = .bB
            case .cSh:
                self = .cSh
            case .dSh:
                self = .dSh
            case .eSh:
                self = .eSh
            case .fSh:
                self = .fSh
            case .gSh:
                self = .gSh
            case .aSh:
                self = .aSh
            case .bSh:
                self = .bSh
            default:
                self = .c
            }
        }
    }
    //...
}

Root

struct Root: Note {
    var noteName: String {
        return key.name
    }

    var rootKey: KeyName.Root
    var noteNum: NoteNum
    var num: Int {return noteNum.num}
    var enharm: Enharmonic

    var degName: (name: DegName.Name, short: DegName.Short, long: DegName.Long) {
        return (name: DegName.Name(.root), short: DegName.Short(.root), long: DegName.Long(.root))
    }

    var key: KeyName

    init(noteNum: NoteNum = .zero, enharm: Enharmonic = .flat) {
        self.noteNum = noteNum
        self.enharm = enharm

        var ks: KeySwitch {
            return KeySwitch(enharm: enharm)
        }

        var rs: RootSwitch {
            return RootSwitch(enharm: enharm)
        }

        switch noteNum {
        case .zero:
            self.key = ks.pickKey(.c, .bSh)
            self.rootKey = rs.pickRoot(.c, .bSh)
        case .one:
            self.key = ks.pickKey(.dB, .cSh)
            self.rootKey = rs.pickRoot(.dB, .cSh)
        case .two:
            self.key = .d
            self.rootKey = .d
        case .three:
            self.key = ks.pickKey(.eB, .dSh)
            self.rootKey = rs.pickRoot(.eB, .dSh)
        case .four:
            self.key = ks.pickKey(.fB, .e)
            self.rootKey = rs.pickRoot(.fB, .e)
        case .five:
            self.key = ks.pickKey(.f, .eSh)
            self.rootKey = rs.pickRoot(.f, .eSh)
        case .six:
            self.key = ks.pickKey(.gB, .fSh)
            self.rootKey = rs.pickRoot(.gB, .fSh)
        case .seven:
            self.key = .g
            self.rootKey = .g
        case .eight:
            self.key = ks.pickKey(.aB, .gSh)
            self.rootKey = rs.pickRoot(.aB, .gSh)
        case .nine:
            self.key = .a
            self.rootKey = .a
        case .ten:
            self.key = ks.pickKey(.bB, .aSh)
            self.rootKey = rs.pickRoot(.bB, .aSh)
        case .eleven:
            self.key = ks.pickKey(.cB, .b)
            self.rootKey = rs.pickRoot(.cB, .b)
        }
    }

    init(_ key: KeyName.Root) {
        self.key = key.r
        self.rootKey = key
        self.noteNum = self.key.noteNum
        self.enharm = self.key.enharm
    }

    mutating func kSW(ks: KeySwitch) {
        switch noteNum {
        case .zero:
            self.key = ks.pickKey(.c, .bSh)
        case .one:
            self.key = ks.pickKey(.dB, .cSh)
        case .two:
            self.key = .d
        case .three:
            self.key = ks.pickKey(.eB, .dSh)
        case .four:
            self.key = ks.pickKey(.fB, .e)
        case .five:
            self.key = ks.pickKey(.f, .eSh)
        case .six:
            self.key = ks.pickKey(.gB, .fSh)
        case .seven:
            self.key = .g
        case .eight:
            self.key = ks.pickKey(.aB, .gSh)
        case .nine:
            self.key = .a
        case .ten:
            self.key = ks.pickKey(.bB, .aSh)
        case .eleven:
            self.key = ks.pickKey(.cB, .b)
        }
    }

    mutating func swapEnharm() {
        enharm = enharm == .flat ? .sharp : .flat
        kSW(ks: KeySwitch(enharm: enharm))
        rootKey = KeyName.Root(key)
    }

    func enharmSwapped() -> Root {
        return Root(noteNum: noteNum, enharm: enharm == .flat ? .sharp : .flat)
    }
}

DetailChord

(heavily pared down for length...original is about 1400 lines)

struct DetailChord {
    enum DCType {
        case dom7, ma7, mi7, mi7b5, dim7, error
    }

    init(resultChord: ResultChord?, verdict: Verdict = .goodToGo) {
        self.verdict = verdict
        self.dRC = resultChord
        if let rc = dRC {
            switch rc.baseChord.lowerQual {
            case .dom7:
                dct = .dom7
            case .ma7:
                dct = .ma7
            case .mi7:
                dct = .mi7
            case .mi7_b5:
                dct = .mi7b5
            case .dim7:
                dct = .dim7
            }
        } else {
            dct = .error
        }
    }

    var dct: DCType

    var dRC: ResultChord?

    var verdict: Verdict

    var validCombos: [[[Int]]] {
        switch dct {
        case .dom7:
            return Dom7.validCombos
        case .ma7:
            return Maj7.validCombos
        case .mi7:
            return Min7.validCombos
        case .mi7b5:
            return Min7_b5.validCombos
        case .dim7:
            return Dim7.validCombos
        default:
            return [[[]]]
        }
    }

    var tension: [[Int]] {
        switch dct {
        case .dom7:
            return Dom7.tension
        case .ma7:
            return Maj7.tension
        case .mi7:
            return Min7.tension
        case .mi7b5:
            return Min7_b5.tension
        case .dim7:
            return Dim7.tension
        default:
            return [[]]
        }
    }

    func qualSwitcher(validCombos: [[[Int]]], degrees: [Int]) -> Int {
        var validCombosIndex = Int()
        for (index, combos) in validCombos.enumerated() {
            if combos.contains(degrees) {
                validCombosIndex = index
                break
            }
        }

        return validCombosIndex
    }

    var chord: ComboChord {
        mutating get {
            if let rc = dRC {
                let degrees = rc.degrees
                let degreesUnsorted = rc.degreesUnsorted
                let baseChord = rc.baseChord
                let degSet = rc.degSet

                var validCombosIndex = Int()

                func tensionOrGoodToGo(getComboChord: GetComboChord) -> ComboChord {
                    if !tension.contains(degrees) { // good to go!
                        verdict = .goodToGo
                        validCombosIndex = qualSwitcher(validCombos: validCombos, degrees: degrees)
                        return getComboChord(degSet, validCombosIndex)
                    } else { // tension!
                        verdict = .tension
                        if let tensionQual = rc.baseChord.qualSuffix as? Suffix.Lower {
                            return TensionChord(tensionQual, rc.degreesUnsorted)
                        } else {
                            return ErrorChord()
                        }
                    }
                }

                switch dct {
                case .dom7:
                    return tensionOrGoodToGo(getComboChord: Dom7.getComboChord(degSet:validCombosIndex:))
                case .ma7:
                    return tensionOrGoodToGo(getComboChord: Maj7.getComboChord(degSet:validCombosIndex:))
                case .mi7:
                    return tensionOrGoodToGo(getComboChord: Min7.getComboChord(degSet:validCombosIndex:))
                case .mi7b5:
                    return tensionOrGoodToGo(getComboChord: Min7_b5.getComboChord(degSet:validCombosIndex:))
                case .dim7:
                    return tensionOrGoodToGo(getComboChord: Dim7.getComboChord(degSet:validCombosIndex:))
                case .error:
                    return ErrorChord()
                }
            } else {
                print("rc not found!")
                dct = .error
                return ErrorChord()
            }
        }
    }

    struct Dom7: DetailChordType {
        static let matches = Mixolydian.validCombos + LydianDom.validCombos + HalfWholeDim.validCombos + AltP5.validCombos + MelodicMinor_Chord.validCombos + HexatonicSh9Sh11_Chord.validCombos + HalfWholeDimFlat13_Chord.validCombos

        static let validCombos: [[[Int]]] = [Mixolydian.validCombos, LydianDom.validCombos, HalfWholeDim.validCombos, AltP5.validCombos, MelodicMinor_Chord.validCombos, HexatonicSh9Sh11_Chord.validCombos, HalfWholeDimFlat13_Chord.validCombos]

        static let tension = [[0, 1, 4, 5, 7, 8, 10], [0, 4, 7, 8, 10, 11], [0, 4, 5, 7, 9, 10], [0, 2, 4, 7, 10, 11], [0, 2, 4, 5, 7, 10], [0, 3, 4, 6, 7, 10, 11], [0, 2, 4, 5, 7, 9, 10], [0, 4, 7, 10, 11], [0, 4, 5, 7, 8, 10], [0, 3, 4, 7, 8, 10, 11], [0, 1, 4, 5, 7, 10], [0, 2, 4, 6, 7, 10, 11], [0, 1, 4, 5, 7, 9, 10], [0, 3, 4, 7, 10, 11], [0, 2, 4, 5, 7, 8, 10], [0, 4, 5, 7, 8, 10, 11], [0, 2, 4, 7, 8, 10, 11], [0, 2, 4, 5, 7, 10, 11], [0, 3, 4, 5, 7, 10], [0, 4, 5, 7, 10], [0, 4, 6, 7, 10, 11], [0, 4, 7, 9, 10, 11], [0, 1, 4, 6, 7, 10, 11]]

        static let tensionTones = [5, 11]

        static func getComboChord(degSet: Set<Int>, validCombosIndex: Int) -> ComboChord {
            switch validCombosIndex {
            case 0: // mixolydian
                switch degSet {
                case let degs where degs.isSuperset(of: Dom7.Mixolydian.XIII.uprStrNotes): // 13
                    return Dom7.Mixolydian.xiii
                // sus4/sus2 on 2nd, sus2 on 5th, min or sus 4 triad on maj6
                case let degs where degs.isSuperset(of: Dom7.Mixolydian.Nine.uprStrNotes): // 9
                    // sus2 on root, min or sus4 triad on p5
                    return Dom7.Mixolydian.nine
                default: // 7
                    //maj triad on root, dim triad on 3rd
                    return Dom7.Mixolydian.seven
                }
            case 1: // lydian dominant
                // similar structure to case 0
            case 2: // half-whole dim
                // similar structure to case 0
            case 3:
            // similar structure to case 0
            case 4: // 5th mode melodic minor
                // similar structure to case 0
            case 5: // hexatonicSh9Sh11
            // similar structure to case 0
            default: // half-whole dim(b13)
                // similar structure to case 0
            }
        }

        var chordType: ComboChord = Mixolydian.seven

        enum Mixolydian: ComboChord {

            case seven, nine, xiii

            var scale: ScaleDetails {
                switch self {
                default:
                    return Major(mode: .five, modeOffset: 0)
                }
            }

            static let validCombos: [[Int]] = Seven.validCombos + Nine.validCombos + XIII.validCombos

            struct Seven {
                static let validCombos = [[0, 4, 7, 10]]
                static let uprStrNotes: [Int] = []
            }

            struct Nine {
                static let validCombos: [[Int]] = [[0, 2, 4, 7, 10]]
                static let uprStrNotes: [Int] = [2]
            }

            struct XIII {
                static let validCombos: [[Int]] = [[0, 2, 4, 7, 9, 10], [0, 4, 7, 9, 10]]
                static let uprStrNotes: [Int] = [9]
            }

            var quality: Suffix  {
                switch self {
                case .seven:
                    return .sev
                case .nine:
                    return .nine
                case .xiii:
                    return .xiii
                }
            }

            var uprStrNotes: [Int] {
                switch self {
                case .seven:
                    return Seven.uprStrNotes
                case .nine:
                    return Nine.uprStrNotes
                case .xiii:
                    return XIII.uprStrNotes
                }
            }
        }

        enum LydianDom: ComboChord {
            // same structure as Mixolydian
        }

        enum HalfWholeDim: ComboChord {
            // same structure as Mixolydian
        }

        enum AltP5: ComboChord {
            // same structure as Mixolydian
        }

        enum HexatonicSh9Sh11_Chord: ComboChord {
            // same structure as Mixolydian
        }

        enum MelodicMinor_Chord: ComboChord {
            // same structure as Mixolydian
        }

        enum HalfWholeDimFlat13_Chord: ComboChord {
            // same structure as Mixolydian
        }
    }

    struct Maj7: DetailChordType {
        // same structure as Dom7
    }

    struct Min7: DetailChordType {
        // same structure as Dom7
    }

    struct Min7_b5: DetailChordType {
        // same structure as Dom7
    }

    struct Dim7: DetailChordType {
        // same structure as Dom7
    }
}

Body:
Not sure if it will fit your usage, but maybe you can make ComboChord generic as well

protocol ComboChord {
    associatedtype Scale: ScaleDetails
    var scale: Scale { get }
}

And then use it like this

struct Chord: ComboChord {

    var scale: DiminishedScale

}


来源: stackexchange

问:
Numpy empty array changes value after creating normal array
I read on the official numpy page that there was an alternative to creating an initialised array without using just zeros:

empty, unlike zeros, does not set the array values to zero, and may therefore be marginally faster.

I created two functions below that demonstrate an unusual issue with using this function:

```<code>import numpy as np

def getInitialisedArray():
    return np.empty((), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))
</code>```

If I just call getInitialisedArray() on its own, here is what it outputs:

```<code>>>> getInitialisedArray()
0.007812501848093234
</code>```

And if I just call the createFloatArray() function:

```<code>>>> createFloatArray(3.1415)
3.1415
</code>```

This all seems fine, but if I repeat the test and call the getInitialisedArray() after creating the float array, there is an issue:

```<code>print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())
</code>```

Output:

```<code>>>>
0.007812501848093234
3.1415
3.1415
</code>```

It seems the second call to get an initialised array gets the same value as what was put in the normal np.array(). I don't get why this occurs. Shouldn't they be separate arrays that have no link between each other?

--- Update ---

I repeated this and changed the size of the empty array:

```<code>import numpy as np

def getInitialisedArray():
    # Changed size to 2 x 2
    return np.empty((2, 2), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())
</code>```

Output:

```<code>[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]
3.1415
[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]
</code>```

This is the sort of output I was expecting, but here it works because I changed the size. Does size now affect if an empty array takes on the same value of a normal np.array()?

答:
From the documentation, np.empty() will "return a new array of given shape and type, without initializing entries."  This should mean that it will just allocate a space in memory for the variable it is assigned to.  Whatever the data in the memory space is will not be changed.

In the first example, you are printing the return from getInitialisedArray without actually storing it. Python must then know you didn't store the address of that value.  Then python will keep that address for the next value that needs an address.  Since createFloatArray does not store the address as well, the value in the address will be changed to 3.1415, and python will keep the address for the next assignment.  When you call getInitialisedArray again, it will use that address again and print out 3.1415.  If you change the datatype however (such as changing the dimensions of the array), depending on how python handles that datatype, it might need more blocks of memory and have to get a different address.  In theory, if createFloatArray was the same shape as getInitialisedArray, it could have the same behavior.

WARNING! I would highly recommend not doing this.  It is possible that python or your system in general will perform a task between those two operations which would change the memory address between calls even if it is the same datatype.

ContentLicense: CC BY-SA 4.0

Body:
I read on the official numpy page that there was an alternative to creating an initialised array without using just zeros:

empty, unlike zeros, does not set the array values to zero, and may therefore be marginally faster.

I created two functions below that demonstrate an unusual issue with using this function:

import numpy as np

def getInitialisedArray():
    return np.empty((), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

If I just call getInitialisedArray() on its own, here is what it outputs:

>>> getInitialisedArray()
0.007812501848093234

And if I just call the createFloatArray() function:

>>> createFloatArray(3.1415)
3.1415

This all seems fine, but if I repeat the test and call the getInitialisedArray() after creating the float array, there is an issue:

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Output:

>>>
0.007812501848093234
3.1415
3.1415

It seems the second call to get an initialised array gets the same value as what was put in the normal np.array(). I don't get why this occurs. Shouldn't they be separate arrays that have no link between each other?

--- Update ---

I repeated this and changed the size of the empty array:

import numpy as np

def getInitialisedArray():
    # Changed size to 2 x 2
    return np.empty((2, 2), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Output:

[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]
3.1415
[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]

This is the sort of output I was expecting, but here it works because I changed the size. Does size now affect if an empty array takes on the same value of a normal np.array()?


问:
Laravel Collection Transform/Map Method Inconsistent Behaviour
In my HTML frontend, I have a jQuery DataTable displaying all records fetched via AJAX from the database - a rather pretty straight forward thing. I use the Laravel Collection's ->transform(function($o){ . . . }) to iterate through the collection and return it in an array-esque manner. Just think of the following piece of code in a controller:

```<code>        $cAllRecords = DatabaseRecord::all();
        if(!empty($aData['sFilterIds']))
        {
            $cAllRecords = $cAllRecords->whereIn('creator', explode(',', $aData['sFilterIds']));
        }
        return response()->json(['data' => $cAllRecords->transform(function ($oDatabaseRecord) {
            /** @var $oDatabaseRecord DatabaseRecord */
            $sActionsHtml = '<a href="#">edit</a>';
            $sUrl = route('some.route', ['iDatabaseRecordId' => $oDatabaseRecord->getAttribute('od')]);
            return [
                $oDatabaseRecord->getAttribute('id'),
                $oDatabaseRecord->getAttribute('updated_at')->toDateTimeString(),
                $oDatabaseRecord->getAttribute('created_at')->toDateTimeString(),
                $sActionsHtml
            ];
        })]);
</code>```

I'm actually just filtering for records created by certain user IDs (the whereIn() call in line 4. However, the response sent back to the client looks different for different users filtered leading the jQuery table to show 'no records available', as it had received an malformed answer from the server. For one user, the response looks like this:

```<code>{
   "data":[
      [
         1,
         "2019-05-29 16:44:53",
         "2019-05-29 16:44:53",
         "<a href=\"#\">edit<\/a>"
      ]
   ]
}
</code>```

This is a correctly formed server response and will show up in the table regularly. Great! Now something that drives me insane - the same code for another user (ID 1, while the first request was for user ID 2) returns this:

```<code>{
   "data":{
      "1":[
         3,
         "2019-05-29 17:08:49",
         "2019-05-29 17:08:49",
         "<a href=\"#\">edit<\/a>"
      ]
   }
}
</code>```

which, pretty obviously, is malformed and is not correctly parsed by the datatable. OK, now combing them two filters and filtering for user ID 1 and 2 will, again, return the response correctly formatted:

```<code>{
   "data":[
      [
         1,
         "2019-05-29 16:44:53",
         "2019-05-29 16:44:53",
         "<a href=\"#\">edit<\/a>"
      ],
      [
         3,
         "2019-05-29 17:08:49",
         "2019-05-29 17:08:49",
         "<a href=\"#\">edit<\/a>"
      ]
   ]
}
</code>```

I tried a number of things, none of which had worked since it's merely guessing why it could work with one user and not with another. (Things like reversing the order of IDs to be filtered, etc., but I found out that the filtering is not the problem. It MUST be the transform, which behaves inconsistent.)

Any ideas on why this happens and how to tackle it? I mean, it's not the only way to achieve what I'm after, I was using ->each() and array_push for all the time before but wanted to get rid of it for the sake of making use of Laravel's helpers (or possibilites) - the manual iteration and array pushing process worked out seamlessly before, and even other parts of the app work well with the Collection transform over array iteration and pushing. Why doesn't it here?

Update: The ->map() collection method behaves exactly same. Map, as opposed by transform, does not alter the collection itself. However, this should not be a relevant part within this application any way. I really can't understand what's going wrong. Is this possibly Laravel's fault?

答:
@Cvetan Mihaylov's answer made me look at all the available collection methods (https://laravel.com/docs/5.8/collections#available-methods) and I found <code>->values()</code> to return the values reindexed. And - that did the trick! :-) </p>

```<code>return response()->json(['data' => $cAllRecords->transform(function ($oDatabaseRecord) {
        /** @var $oDatabaseRecord DatabaseRecord */
        $sActionsHtml = '<a href="#">edit</a>';
        $sUrl = route('some.route', ['iDatabaseRecordId' => $oDatabaseRecord->getAttribute('od')]);
        return [
            $oDatabaseRecord->getAttribute('id'),
            $oDatabaseRecord->getAttribute('updated_at')->toDateTimeString(),
            $oDatabaseRecord->getAttribute('created_at')->toDateTimeString(),
            $sActionsHtml
        ];
    })->values()]);
</code>```

Body:
In my HTML frontend, I have a jQuery DataTable displaying all records fetched via AJAX from the database - a rather pretty straight forward thing. I use the Laravel Collection's ->transform(function($o){ . . . }) to iterate through the collection and return it in an array-esque manner. Just think of the following piece of code in a controller:

        $cAllRecords = DatabaseRecord::all();
        if(!empty($aData['sFilterIds']))
        {
            $cAllRecords = $cAllRecords->whereIn('creator', explode(',', $aData['sFilterIds']));
        }
        return response()->json(['data' => $cAllRecords->transform(function ($oDatabaseRecord) {
            /** @var $oDatabaseRecord DatabaseRecord */
            $sActionsHtml = 'edit';
            $sUrl = route('some.route', ['iDatabaseRecordId' => $oDatabaseRecord->getAttribute('od')]);
            return [
                $oDatabaseRecord->getAttribute('id'),
                $oDatabaseRecord->getAttribute('updated_at')->toDateTimeString(),
                $oDatabaseRecord->getAttribute('created_at')->toDateTimeString(),
                $sActionsHtml
            ];
        })]);

I'm actually just filtering for records created by certain user IDs (the whereIn() call in line 4. However, the response sent back to the client looks different for different users filtered leading the jQuery table to show 'no records available', as it had received an malformed answer from the server. For one user, the response looks like this:

{
   "data":[
      [
         1,
         "2019-05-29 16:44:53",
         "2019-05-29 16:44:53",
         "edit<\/a>"
      ]
   ]
}

This is a correctly formed server response and will show up in the table regularly. Great! Now something that drives me insane - the same code for another user (ID 1, while the first request was for user ID 2) returns this:

{
   "data":{
      "1":[
         3,
         "2019-05-29 17:08:49",
         "2019-05-29 17:08:49",
         "edit<\/a>"
      ]
   }
}

which, pretty obviously, is malformed and is not correctly parsed by the datatable. OK, now combing them two filters and filtering for user ID 1 and 2 will, again, return the response correctly formatted:

{
   "data":[
      [
         1,
         "2019-05-29 16:44:53",
         "2019-05-29 16:44:53",
         "edit<\/a>"
      ],
      [
         3,
         "2019-05-29 17:08:49",
         "2019-05-29 17:08:49",
         "edit<\/a>"
      ]
   ]
}

I tried a number of things, none of which had worked since it's merely guessing why it could work with one user and not with another. (Things like reversing the order of IDs to be filtered, etc., but I found out that the filtering is not the problem. It MUST be the transform, which behaves inconsistent.)

Any ideas on why this happens and how to tackle it? I mean, it's not the only way to achieve what I'm after, I was using ->each() and array_push for all the time before but wanted to get rid of it for the sake of making use of Laravel's helpers (or possibilites) - the manual iteration and array pushing process worked out seamlessly before, and even other parts of the app work well with the Collection transform over array iteration and pushing. Why doesn't it here?

Update: The ->map() collection method behaves exactly same. Map, as opposed by transform, does not alter the collection itself. However, this should not be a relevant part within this application any way. I really can't understand what's going wrong. Is this possibly Laravel's fault?

Body:
@Cvetan Mihaylov's answer made me look at all the available collection methods (https://laravel.com/docs/5.8/collections#available-methods) and I found ->values() to return the values reindexed. And - that did the trick! :-)

return response()->json(['data' => $cAllRecords->transform(function ($oDatabaseRecord) {
        /** @var $oDatabaseRecord DatabaseRecord */
        $sActionsHtml = '<a href="#">edit</a>';
        $sUrl = route('some.route', ['iDatabaseRecordId' => $oDatabaseRecord->getAttribute('od')]);
        return [
            $oDatabaseRecord->getAttribute('id'),
            $oDatabaseRecord->getAttribute('updated_at')->toDateTimeString(),
            $oDatabaseRecord->getAttribute('created_at')->toDateTimeString(),
            $sActionsHtml
        ];
    })->values()]);


问:
How to use <Xsl: apply-templates match="othertemplate" > inside another template <xsl:template match="sometemplate">
Curent output Expected output I am trying to populate a dropdown list using a xsl template inside another xsl template match. I get empty dropdown. How to get the values in the dropdwon from a xsl template ?

I have 2 templates. Template 1 has a list of preferences and template 2 has list of user details. I am trying to populate a table with list of user details. And i need to populate the preference list as once of the column in table as drop down values.  I am getting an empty dropdown list. attached image for reference

XML inputs

```<code><USERLIST>
    <record num="0"><SERIALNUMER>01</SERIALNUMER><NAME>Rahul</NAME>
  <SELECTEDPREFERENCE>Pref2</SELECTEDPREFERENCE></record>
    <record num="1"><SERIALNUMER>02</SERIALNUMER><NAME>Khan</NAME>
  <SELECTEDPREFERENCE>Pref4</SELECTEDPREFERENCE></record>
    <record num="2"><SERIALNUMER>03</SERIALNUMER><NAME>Raju</NAME>
  <SELECTEDPREFERENCE>Pref2</SELECTEDPREFERENCE></record>
    </USERLIST>

    <PREFERENCE_LIST>
    <record num="0"><PREFERENCE_ID>pref1</PREFERENCE_ID></record>
    <record num="1"><PREFERENCE_ID>pref2</PREFERENCE_ID></record>
    <record num="2"><PREFERENCE_ID>pref3</PREFERENCE_ID></record>
    <record num="3"><PREFERENCE_ID>pref4</PREFERENCE_ID></record>
    <record num="4"><PREFERENCE_ID>pref5</PREFERENCE_ID></record>
    </PREFERENCE_LIST>
</code>```

XSLT

```<code>    <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
    <xsl:template match="/page">
            <div style="margin: 0px; background-color: #ffffff;">
            <form action="Useraction" method="post" id="user_search" onsubmit="if (document.getElementById('user_search').action.value=='') return false; else return true;" style="margin: 0px; border: 0px; padding-top: 0px;">

                    <hr style="color: #003399; width: 100%; height: 3px; border: 0px; margin-top: 0px; margin-bottom: 5px;" />
                    <table style="width: 100%; text-align: center; border: 0; background-color: #ffffff; margin-bottom: 1px; margin-top: 1px;" cellspacing="0" cellpadding="0">
                        <tr>
                            <td class="tableheader3" style="white-space: nowrap; width: 30px;height:30px">
                                <p align="center">
                                    <input class="tabletext" type="button" value="Alle" onclick="javascript:markAll(document.getElementById('user_search'), 'UserId_')" style="width: 50px;" />
                                </p>
                            </td>
                            <td class="tableheader5" style="width: 30px; text-align: center;">Serial Number</td>
                            <td class="tableheader5" style="white-space: nowrap; width: 60px;">Name</td>
                            <td class="tableheader5" style="white-space: nowrap; width: 40px;">Preference</td>

                        </tr>

                        <tr>
                            <td colspan="12">
                                <hr style="border-top: 1px solid #1A15B7; background: transparent;"> </hr>
                            </td>
                        </tr>
                        <xsl:if test="USERLIST/record">

                        <xsl:apply-templates select="USERLIST/record" />
                        <tr>
                            <td colspan="12">
                                <img src="images/td_background4.jpg" style="width: 100%; height: 5px; border: 0px;" alt="" />
                            </td>
                        </tr>

                        </xsl:if>
                    </table>

            </form>
        </div>

    </xsl:template>

        <xsl:template match="PREFERENCE_LIST/record">
        <xsl:if test="PREFERENCE_ID=/page/parameters/preference">
            <option value="{PREFERENCE_ID }" selected="selected ">
                <xsl:value-of select="PREFERENCE_ID " />
            </option>
        </xsl:if>
        <xsl:if test="not(PREFERENCE_ID =/page/parameters/preference)">
            <option value="{PREFERENCE_ID }">
                <xsl:value-of select="PREFERENCE_ID " />
            </option>
        </xsl:if>
    </xsl:template>
    <xsl:template match="USERLIST/record">
    <tr>
     <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="SERIALNUMER" />
     </td>
     <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="NAME" />
     </td>
     <td class="tabletext" style="white-space: nowrap;">
      <select class="tabletext" name="preference" style="width:79px;">
        <option><xsl:attribute name="value"><xsl:value-of select="SELECTEDPREFERENCE"/>
        </xsl:attribute></option>
      <option value="" />
          <xsl:apply-templates name="PREFERENCE_LIST/record" />
       </select>
     </td>
    </tr>
    </xsl:template>
</xsl:stylesheet>
</code>```

答:
As mentioned in comments, name is not a valid attribute on xsl:apply-templates, but assuming you changed it to select the reason it did not select anything is that you are currently in a template matching a record element, and so doing <xsl:apply-templates select="PREFERENCE_LIST/record" /> will look for a child element of record called PREFERENCE_LIST, which does not exist.

You need to navigate back up two levels in the hierarchy to get the PREFERENCE_LIST, so you should actually be writing this:

```<code><xsl:apply-templates select="../../PREFERENCE_LIST/record" />
</code>```

I am going to hazard a guess that you want the user's SELECTEDPREFERENCE selected as an option in the drop-down list? In this case, you need to pass the user's selected preference to the record template.

Try this two templates instead

```<code><xsl:template match="PREFERENCE_LIST/record">
  <xsl:param name="pref" />
  <option value="{PREFERENCE_ID}">
    <xsl:if test="$pref = PREFERENCE_ID">
      <xsl:attribute name="selected">selected</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="PREFERENCE_ID " />
  </option>
</xsl:template>

<xsl:template match="USERLIST/record">
  <tr>
    <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="SERIALNUMER" />
    </td>
    <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="NAME" />
    </td>
    <td class="tabletext" style="white-space: nowrap;">
      <select class="tabletext" name="preference" style="width:79px;">
        <option value="" />
        <xsl:variable name="selectPref" select="translate(SELECTEDPREFERENCE, 'P', 'p')" />
        <xsl:apply-templates select="../../PREFERENCE_LIST/record">
          <xsl:with-param name="pref" select="$selectPref" />
        </xsl:apply-templates>
      </select>
    </td>
  </tr>
</xsl:template>
</code>```

Note the use of translate was simply because the check would be case-sensitive, and so Pref2 would not match pref2.

See it in action at http://xsltfiddle.liberty-development.net/ncdD7mS

Body:
Curent output Expected output I am trying to populate a dropdown list using a xsl template inside another xsl template match. I get empty dropdown. How to get the values in the dropdwon from a xsl template ?

I have 2 templates. Template 1 has a list of preferences and template 2 has list of user details. I am trying to populate a table with list of user details. And i need to populate the preference list as once of the column in table as drop down values.  I am getting an empty dropdown list. attached image for reference

XML inputs

<USERLIST>
    <record num="0"><SERIALNUMER>01</SERIALNUMER><NAME>Rahul</NAME>
  <SELECTEDPREFERENCE>Pref2</SELECTEDPREFERENCE></record>
    <record num="1"><SERIALNUMER>02</SERIALNUMER><NAME>Khan</NAME>
  <SELECTEDPREFERENCE>Pref4</SELECTEDPREFERENCE></record>
    <record num="2"><SERIALNUMER>03</SERIALNUMER><NAME>Raju</NAME>
  <SELECTEDPREFERENCE>Pref2</SELECTEDPREFERENCE></record>
    </USERLIST>

    <PREFERENCE_LIST>
    <record num="0"><PREFERENCE_ID>pref1</PREFERENCE_ID></record>
    <record num="1"><PREFERENCE_ID>pref2</PREFERENCE_ID></record>
    <record num="2"><PREFERENCE_ID>pref3</PREFERENCE_ID></record>
    <record num="3"><PREFERENCE_ID>pref4</PREFERENCE_ID></record>
    <record num="4"><PREFERENCE_ID>pref5</PREFERENCE_ID></record>
    </PREFERENCE_LIST>

XSLT

    <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
    <xsl:template match="/page">

            <form action="Useraction" method="post" id="user_search" onsubmit="if (document.getElementById('user_search').action.value=='') return false; else return true;" style="margin: 0px; border: 0px; padding-top: 0px;">

                                    <input class="tabletext" type="button" value="Alle" onclick="javascript:markAll(document.getElementById('user_search'), 'UserId_')" style="width: 50px;" />

                            Serial Number
                            Name
                            Preference

                        <xsl:if test="USERLIST/record">

                        <xsl:apply-templates select="USERLIST/record" />

                        </xsl:if>

            </form>

    </xsl:template>

        <xsl:template match="PREFERENCE_LIST/record">
        <xsl:if test="PREFERENCE_ID=/page/parameters/preference">
            <option value="{PREFERENCE_ID }" selected="selected ">
                <xsl:value-of select="PREFERENCE_ID " />
            </option>
        </xsl:if>
        <xsl:if test="not(PREFERENCE_ID =/page/parameters/preference)">
            <option value="{PREFERENCE_ID }">
                <xsl:value-of select="PREFERENCE_ID " />
            </option>
        </xsl:if>
    </xsl:template>
    <xsl:template match="USERLIST/record">

      <xsl:value-of select="SERIALNUMER" />

      <xsl:value-of select="NAME" />

      <select class="tabletext" name="preference" style="width:79px;">
        <option><xsl:attribute name="value"><xsl:value-of select="SELECTEDPREFERENCE"/>
        </xsl:attribute></option>
      <option value="" />
          <xsl:apply-templates name="PREFERENCE_LIST/record" />
       </select>

    </xsl:template>
</xsl:stylesheet>

Body:
As mentioned in comments, name is not a valid attribute on xsl:apply-templates, but assuming you changed it to select the reason it did not select anything is that you are currently in a template matching a record element, and so doing <xsl:apply-templates select="PREFERENCE_LIST/record" /> will look for a child element of record called PREFERENCE_LIST, which does not exist.

You need to navigate back up two levels in the hierarchy to get the PREFERENCE_LIST, so you should actually be writing this:

<xsl:apply-templates select="../../PREFERENCE_LIST/record" />

I am going to hazard a guess that you want the user's SELECTEDPREFERENCE selected as an option in the drop-down list? In this case, you need to pass the user's selected preference to the record template.

Try this two templates instead

<xsl:template match="PREFERENCE_LIST/record">
  <xsl:param name="pref" />
  <option value="{PREFERENCE_ID}">
    <xsl:if test="$pref = PREFERENCE_ID">
      <xsl:attribute name="selected">selected</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="PREFERENCE_ID " />
  </option>
</xsl:template>

<xsl:template match="USERLIST/record">
  <tr>
    <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="SERIALNUMER" />
    </td>
    <td class="tabletext" style="white-space: nowrap;">
      <xsl:value-of select="NAME" />
    </td>
    <td class="tabletext" style="white-space: nowrap;">
      <select class="tabletext" name="preference" style="width:79px;">
        <option value="" />
        <xsl:variable name="selectPref" select="translate(SELECTEDPREFERENCE, 'P', 'p')" />
        <xsl:apply-templates select="../../PREFERENCE_LIST/record">
          <xsl:with-param name="pref" select="$selectPref" />
        </xsl:apply-templates>
      </select>
    </td>
  </tr>
</xsl:template>

Note the use of translate was simply because the check would be case-sensitive, and so Pref2 would not match pref2.

See it in action at http://xsltfiddle.liberty-development.net/ncdD7mS


问:
Kotlin button onClickListener event inside a fragment
I'm trying to catch the onClick event from a button inside a fragment but it's not working.

Any tip?

I have this main activity and I call the fragment throught a bottomNavigation.
MainActivity.kt:

```<code>    class MainActivity : FragmentActivity()  {

    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                showFragmentSetup()
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }

    fun showFragmentSetup(){
        val setupFragment = SetupFragment()
        val manager = supportFragmentManager
        val transaction = manager.beginTransaction()
        transaction.replace(R.id.setupFragment, setupFragment)
        transaction.addToBackStack(null)
        transaction.commit()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
    }
}
</code>```

The activity_main.xml is the container of the linearLayout which will cointain the fragment.

activity_main.xml

```<code>    <LinearLayout
        android:id="@+id/setupFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />
</code>```

My fragment is simple it just have a button and i want to catch the onClickEvent from this button

```<code>    class SetupFragment : Fragment(){

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_setup, container, false)

        val view: View = inflater!!.inflate(R.layout.fragment_setup, container, false)

        btnSetup.setOnClickListener { view ->
            Log.d("btnSetup", "Selected")
        }

        // Return the fragment view/layout
        return view
    }

    companion object {
        fun newInstance(): SetupFragment {
            return SetupFragment()
        }
    }

}
</code>```

答:
I think you should use "onViewCreated" function in your "SetupFragment"</p>

```<code>override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    btnSetup.setOnClickListener { view ->
        Log.d("btnSetup", "Selected")
    }
}
</code>```

Body:
I'm trying to catch the onClick event from a button inside a fragment but it's not working.

Any tip?

I have this main activity and I call the fragment throught a bottomNavigation.
MainActivity.kt:

    class MainActivity : FragmentActivity()  {

    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                showFragmentSetup()
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }

    fun showFragmentSetup(){
        val setupFragment = SetupFragment()
        val manager = supportFragmentManager
        val transaction = manager.beginTransaction()
        transaction.replace(R.id.setupFragment, setupFragment)
        transaction.addToBackStack(null)
        transaction.commit()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
    }
}

The activity_main.xml is the container of the linearLayout which will cointain the fragment.

activity_main.xml

    <LinearLayout
        android:id="@+id/setupFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

My fragment is simple it just have a button and i want to catch the onClickEvent from this button

    class SetupFragment : Fragment(){

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_setup, container, false)

        val view: View = inflater!!.inflate(R.layout.fragment_setup, container, false)

        btnSetup.setOnClickListener { view ->
            Log.d("btnSetup", "Selected")
        }

        // Return the fragment view/layout
        return view
    }

    companion object {
        fun newInstance(): SetupFragment {
            return SetupFragment()
        }
    }

}

Body:
I think you should use "onViewCreated" function in your "SetupFragment"

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    btnSetup.setOnClickListener { view ->
        Log.d("btnSetup", "Selected")
    }
}


问:
Can I run a try-catch for a command with exec-maven-plugin?
I have a situation where a command may have different names in different environments. In these environments it is not possible or not permitted for me to alter the name of the command. Given that I know the possible names of the command across the environments I need to be able to run my maven command across all of them without changing the source code every time it is run on a different system.

Say I have the following in my pom.xml where "command" is either cmake or ${env.CMAKE_V_HOME}/cmake:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.3.2</version>

      <executions>
        <execution>
          <id>cmake-generate</id>
          <phase>process-resources</phase>
          <goals><goal>exec</goal></goals>

          <configuration>
            <executable>command</executable>
            <workingDirectory>${project.build.directory}/native</workingDirectory>
            <arguments><argument>${project.basedir}/mylib/</argument></arguments>
            <skip>${skipCMake}</skip>
          </configuration>
        </execution>
      </executions>

    </plugin>
  </plugins>
</build>
```

How can I run the above file given that "command" may be under different known names on different systems, without having to change to source code every time it needs to run on a different system?

答:
Perhaps you will be able to achieve the desired logic using a bash script.
Having said that, the situation of having different names on different systems is a bad practice.</p>

Body:
I have a situation where a command may have different names in different environments. In these environments it is not possible or not permitted for me to alter the name of the command. Given that I know the possible names of the command across the environments I need to be able to run my maven command across all of them without changing the source code every time it is run on a different system.

Say I have the following in my pom.xml where "command" is either cmake or ${env.CMAKE_V_HOME}/cmake:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.3.2</version>

      <executions>
        <execution>
          <id>cmake-generate</id>
          <phase>process-resources</phase>
          <goals><goal>exec</goal></goals>

          <configuration>
            <executable>command</executable>
            <workingDirectory>${project.build.directory}/native</workingDirectory>
            <arguments><argument>${project.basedir}/mylib/</argument></arguments>
            <skip>${skipCMake}</skip>
          </configuration>
        </execution>
      </executions>

    </plugin>
  </plugins>
</build>

How can I run the above file given that "command" may be under different known names on different systems, without having to change to source code every time it needs to run on a different system?


问:
How to overwrite a hardcoded function argument with the dots (...) parameter?
I am trying to make a plot function with a set of default values and the flexibility to change these values by using any argument the plot function accepts inside the dots (...) argument. An example:

```<code>PlotIt <- function(x, y, ...) {
  plot(x, y, type = "l", asp = 1, ...)
}

x <- 1:10
y <- 10:1

PlotIt(x = x, y = y)
# Returns a plot
PlotIt(x = x, y = y, asp = NA)
# Error in plot.default(x, y, type = "l", asp = 1, ...) :
#  formal argument "asp" matched by multiple actual arguments
</code>```

The error is naturally because I try to pass the asp argument twice into plot. So far my best clumsy attempt is to make an if-else statement to take this into account (the approach is modified from here):

```<code>PlotIt2 <- function(x, y, ...) {

  mc <- match.call(expand.dots = FALSE)

  if(names(mc$...) %in% "asp") {
  plot(x, y, type = "l", ...)
  } else {
  plot(x, y, type = "l", asp = 1, ...)
  }

}

PlotIt2(x = x, y = y, asp = NA)
# works
</code>```

To do this for all possible parameters one can set in with the ... argument, I would need to write a long if-else statement. Is there a more elegant way of doing this?

The question is related to this one with the difference that I want to automatically overwrite all parameters set by the ... argument.

答:
If you want to use base R only,
you can put everything in a list and remove duplicates based on the argument names
(making sure that the defaults are last so that they are removed if they are present in ...):

```<code>PlotIt <- function(x, y, ...) {
  arguments <- list(
    x = x,
    y = y,
    ...,
    type = "l",
    asp = 1
  )

  arguments <- arguments[!duplicated(names(arguments))]

  do.call("plot", arguments)
}
</code>```

If you don't mind depending on rlang,
you could also do the following,
using .homonyms to get the same functionality
(and check the plot's labels for the axes,
it'll be different between the base R and rlang versions):

```<code>PlotIt <- function(x, y, ...) {
  require("rlang")
  arguments <- rlang::dots_list(
    rlang::expr(x),
    rlang::expr(y),
    ...,
    type = "l",
    asp = 1,
    .homonyms = "first"
  )

  call <- rlang::call2("plot", !!!arguments)
  eval(call)
}
</code>```

Body:
I am trying to make a plot function with a set of default values and the flexibility to change these values by using any argument the plot function accepts inside the dots (...) argument. An example:

PlotIt <- function(x, y, ...) {
  plot(x, y, type = "l", asp = 1, ...)
}

x <- 1:10
y <- 10:1

PlotIt(x = x, y = y)
# Returns a plot
PlotIt(x = x, y = y, asp = NA)
# Error in plot.default(x, y, type = "l", asp = 1, ...) :
#  formal argument "asp" matched by multiple actual arguments

The error is naturally because I try to pass the asp argument twice into plot. So far my best clumsy attempt is to make an if-else statement to take this into account (the approach is modified from here):

PlotIt2 <- function(x, y, ...) {

  mc <- match.call(expand.dots = FALSE)

  if(names(mc$...) %in% "asp") {
  plot(x, y, type = "l", ...)
  } else {
  plot(x, y, type = "l", asp = 1, ...)
  }

}

PlotIt2(x = x, y = y, asp = NA)
# works

To do this for all possible parameters one can set in with the ... argument, I would need to write a long if-else statement. Is there a more elegant way of doing this?

The question is related to this one with the difference that I want to automatically overwrite all parameters set by the ... argument.

Body:
If you want to use base R only,
you can put everything in a list and remove duplicates based on the argument names
(making sure that the defaults are last so that they are removed if they are present in ...):

PlotIt <- function(x, y, ...) {
  arguments <- list(
    x = x,
    y = y,
    ...,
    type = "l",
    asp = 1
  )

  arguments <- arguments[!duplicated(names(arguments))]

  do.call("plot", arguments)
}

If you don't mind depending on rlang,
you could also do the following,
using .homonyms to get the same functionality
(and check the plot's labels for the axes,
it'll be different between the base R and rlang versions):

PlotIt <- function(x, y, ...) {
  require("rlang")
  arguments <- rlang::dots_list(
    rlang::expr(x),
    rlang::expr(y),
    ...,
    type = "l",
    asp = 1,
    .homonyms = "first"
  )

  call <- rlang::call2("plot", !!!arguments)
  eval(call)
}


问:
Jenkins specify a not case with an expression?
I want a Jenkins stage to execute when it isn't the master branch and when a certain parameter is set. I'm doing this:

```<code>stage('Deploy') {
      when {
        allOf {
            expression { return params.ACTION == "create" };
            not {
                anyOf {
                    expression { branch 'master' }
                }
            }
        }
      }
</code>```

But when I run the Jenkins job, this stage is skipped altogether. Something is wrong with the syntax I think but not sure what.

答:
Could try something like:</p>

```<code>stage('Deploy'){
        when {
            expression { return (params.ACTION == "create" && env.BRANCH_NAME !='master')};
        }

    }
</code>```

Body:
I want a Jenkins stage to execute when it isn't the master branch and when a certain parameter is set. I'm doing this:

stage('Deploy') {
      when {
        allOf {
            expression { return params.ACTION == "create" };
            not {
                anyOf {
                    expression { branch 'master' }
                }
            }
        }
      }

But when I run the Jenkins job, this stage is skipped altogether. Something is wrong with the syntax I think but not sure what.

Body:
Could try something like:

stage('Deploy'){
        when {
            expression { return (params.ACTION == "create" && env.BRANCH_NAME !='master')};
        }

    }


问:
MS Access Application - Convert data storage from Access to SQL Server
Bear in mind here, I am not an Access guru. I am proficient with SQL Server and .Net framework. Here is my situation:

A very large MS Access 2007 application was built for my company by a contractor.

The application has been split into two tiers BY ACCESS; there is a front end portion that holds all of the Ms Access forms, and then on the back end part, which are access tables, queries, etc., that is stored on a computer on the network.

Well, of course, there is a need to convert the data storage portion to SQL Server 2005 while keeping all of these GUI forms which were built in Ms Access. This is where I come in.

I have read a little, and have found that you can link the forms or maybe even the access tables to SQL Server tables, but I am still very unsure on what exactly can be done and how to do it.

Has anyone done this? Please comment on any capabilities, limitations, considerations about such an undertaking. Thanks!

答:
Others have suggested upsizing the Jet back end to SQL Server and linking via ODBC. In an ideal world, the app will work beautifully without needing to change anything.

In the real world, you'll find that some of your front-end objects that were engineered to be efficient and fast with a Jet back end don't actually work very well with a server database. Sometimes Jet guesses wrong and sends something really inefficient to the server. This is particular the case with mass updates of records -- in order not to hog server resources (a good thing), Jet will send a single UPDATE statement for each record (which is a bad thing for your app, since it's much, much slower than a single UPDATE statement).

What you have to do is evaluate everything in your app after you've upsized it and where there are performance problems, move some of the logic to the server. This means you may create a few server-side views, or you may use passthrough queries (to hand off the whole SQL statement to SQL Server and not letting Jet worry about it), or you may need to create stored procedures on the server (especially for update operations).

But in general, it's actually quite safe to assume that most of it will work fine without change. It likely won't be as fast as the old Access/Jet app, but that's where you can use SQL Profiler to figure out what the holdup is and re-architect things to be more efficient with the SQL Server back end.

If the Access app was already efficiently designed (e.g., forms are never bound to full tables, but instead to recordsources with restrictive WHERE clauses returning only 1 or a few records), then it will likely work pretty well. On the other hand, if it uses a lot of the bad practices seen in the Access sample databases and templates, you could run into huge problems.

It's my opinion that every Access/Jet app should be designed from the beginning with the idea that someday it will be upsized to use a server back end. This means that the Access/Jet app will actually be quite efficient and speedy, but also that when you do upsize, it will cause a minimum of pain.

OwnerDisplayName: Ronnie Overby

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: David W. Fenton


问:
Rename column name with hyphen (-) in laravel migration
I'm trying to run a laravel migration that renames a particular column in my database but I repeatedly get an error message.

```<code>class ModifyColumnName extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->renameColumn("content-description", "content_description");
        });
    }

}
</code>```

I keep on getting this error message.

```<code>Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for the right syntax to use near '-description content_description VARCHAR(255) DEFAULT NULL' at line 1 (SQL: ALTER TABLE posts CHANGE content-description content_description VARCHAR(255) DEFAULT NULL)
</code>```

答:
Hyphens in database names aren't good and hyphens are a big problem because if you end up mapping a column name to a variable, most languages do not like to have hyphens inside variable names.

But you can use them with the back-tick trick just enclose the column name within back-ticks(`)

```<code>public function up()
{
    Schema::table('posts', function (Blueprint $table) {
        $table->renameColumn("`content-description`", "content_description");
    });
}
</code>```

Body:
I'm trying to run a laravel migration that renames a particular column in my database but I repeatedly get an error message.

class ModifyColumnName extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->renameColumn("content-description", "content_description");
        });
    }

}

I keep on getting this error message.

Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version for the right syntax to use near '-description content_description VARCHAR(255) DEFAULT NULL' at line 1 (SQL: ALTER TABLE posts CHANGE content-description content_description VARCHAR(255) DEFAULT NULL)

Body:
Hyphens in database names aren't good and hyphens are a big problem because if you end up mapping a column name to a variable, most languages do not like to have hyphens inside variable names.

But you can use them with the back-tick trick just enclose the column name within back-ticks(`)

public function up()
{
    Schema::table('posts', function (Blueprint $table) {
        $table->renameColumn("`content-description`", "content_description");
    });
}


问:
How to open a particular file on git bash vim editor itself to edit contents upon error msg “e325-attention-swap-file-already-present-error-in-vi”
Prob Scenario  : I encountered an error msg  “e325-attention-swap-file-already-present-error-in-vi” when I tried to perform a git commit.

Qn: “How do I open that particular file on git bash vim editor itself to peer inside the contents where exactly did the clash occur? I’m not asking how to remove the file form the staging area, I’m asking in particular to open that file on the git bash’s vim editor itself? And if so able, once done, how do I save that file ON the vim editor itself in git bash & exit the irritating modes in vim. PS: can any kind soul give me a useful “f1/-help”-type command that I can use to check to move forward whenever I am stuck in the vim editor mode and not exit the editor altogether each time I encounter sucha prob? Thanks!

答:
vi is a pretty overlay on the ex engine. c.f. this man page for ex in particular.

Any command you enter in vi with a colon prompt (escape, then : followed by your command) is actually an ex command. That's why a lot of people use :q or :x or :wq or :q! (etc) to get out of vi.


问:
Javascript Date Format is displayed differently in Firefox for different locations
I have a javascript code which constructs an HTML page.
The page has a table with a date column. The date format required is mm/dd/yyyy hh:mi:ss AM

In the Javascript I generate this format from below code.

Expected Output is 06/07/2019 6:00:00 PM

At my location when I run the javascript code in my machine located in India, I get the expected result.
But when the client runs it, at his system in the USA, he sees some offset in time.

It appears like mentioned below in Firefox.

6/06/2019 2:00:00 04:00 PM

What could be the reason for this? And how could I resolve it?

```<code>'<span>"06-06-2019 1:00:00 CDT PM".split('-')[1]+'/'+"06-06-2019 1:00:00 CDT PM".split('-')[0]+'/'+"06-06-2019 1:00:00 CDT PM".substr(6, 13).trim()+' '+"06-06-2019 1:00:00 CDT PM".substr(23)</span>'
</code>```

答:
The simple answer is TimeZone Difference. Every people have there own browser and Javascript work on a client side so it is but obvious nature of javascript it will show local date time by default.

you can simply set the value by setting a timezone offset value

```<code>Date.prototype.getUTCLocalDate = function () {
    var target = new Date(this.valueOf());
    var offset = target.getTimezoneOffset();
    var year = target.getUTCFullYear();
    var month = target.getUTCMonth();
    var date = target.getUTCDate();
    var hour = target.getUTCHours();
    var minutes = target.getUTCMinutes();
    var seconds = target.getUTCSeconds();
    return new Date(Date.UTC(year , month , date , hour , minutes + offset, seconds ));
  };
</code>```

Or you can get a server time zone offset by making a rest query and make your own offset to show unique time in everywhere.

Body:
I have a javascript code which constructs an HTML page.
The page has a table with a date column. The date format required is mm/dd/yyyy hh:mi:ss AM

In the Javascript I generate this format from below code.

Expected Output is 06/07/2019 6:00:00 PM

At my location when I run the javascript code in my machine located in India, I get the expected result.
But when the client runs it, at his system in the USA, he sees some offset in time.

It appears like mentioned below in Firefox.

6/06/2019 2:00:00 04:00 PM

What could be the reason for this? And how could I resolve it?

'"06-06-2019 1:00:00 CDT PM".split('-')[1]+'/'+"06-06-2019 1:00:00 CDT PM".split('-')[0]+'/'+"06-06-2019 1:00:00 CDT PM".substr(6, 13).trim()+' '+"06-06-2019 1:00:00 CDT PM".substr(23)'

Body:
The simple answer is TimeZone Difference. Every people have there own browser and Javascript work on a client side so it is but obvious nature of javascript it will show local date time by default.

you can simply set the value by setting a timezone offset value

Date.prototype.getUTCLocalDate = function () {
    var target = new Date(this.valueOf());
    var offset = target.getTimezoneOffset();
    var year = target.getUTCFullYear();
    var month = target.getUTCMonth();
    var date = target.getUTCDate();
    var hour = target.getUTCHours();
    var minutes = target.getUTCMinutes();
    var seconds = target.getUTCSeconds();
    return new Date(Date.UTC(year , month , date , hour , minutes + offset, seconds ));
  };

Or you can get a server time zone offset by making a rest query and make your own offset to show unique time in everywhere.