问:
Updating a binary tree using a pointer
I'm trying to update a self-balancing binary tree.  Normally, you can update it by 1) searching a node, 2) deleting it, 3) and inserting the tree with a new node.  But, I want to see if this is possible simply by retaining a pointer to a node from the first step and updating it so that I can bypass the deletion and insertion and improve the time complexity, especially when it comes to a large number of nodes.

The tree itself is standard binary search tree.

public class TreeNode<T: Comparable>: Equatable {
    public typealias Node = TreeNode<T>

    var key: T?
    var leftChild: Node?
    var rightChild: Node?
    fileprivate weak var parent: Node?

    var isNullLeaf: Bool {
        return key == nil && isLeaf
    }

    var isLeaf: Bool {
        return rightChild == nil && leftChild == nil
    }

    public init(key: T?, leftChild: Node?, rightChild: Node?, parent: Node?) {
        self.key = key
        self.leftChild = leftChild
        self.rightChild = rightChild
        self.parent = parent

        self.leftChild?.parent = self
        self.rightChild?.parent = self
    }

    /// Null leaf
    public convenience init() {
        self.init(key: nil, leftChild: nil, rightChild: nil, parent: nil)
    }

    static public func == <T>(lhs: TreeNode<T>, rhs: TreeNode<T>) -> Bool {
        return lhs.key == rhs.key
    }
}

public final class Tree<T: Comparable> {
    public typealias Node = TreeNode<T>

    fileprivate(set) var root: Node
    fileprivate let nullLeaf = Node()

    public init() {
        root = nullLeaf
    }

    func search(key: T, f: (inout Node) -> Void) {
        search(key: key, node: &root, f:  f)
    }

    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void) {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an argument to a closure so that it retains the connection to the node when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }

    public func insert(key: T) {
       /// insertion logic
    }

    /// Other operations
}
```
<p>My idea was to search the tree through recursion and when a node is found, pass it as an argument to a closure function, which will ultimately be called to update the node.  Also, the found node would be pass by reference.</p>
<pre class="lang-swift prettyprint-override"><code>class Test<T: Comparable> {
    private(set) var tree = Tree<T>()

    func insert(key: T) {
        tree.insert(key: key)
    }

    func update(for node: T, with newNode: T) {
        tree.search(key: node) { foundNode in
            foundNode.key = newNode
        }
    }
}

let test = Test<MyNode>()
let node = MyNode()
let anotherNode = MyNode()
test.insert(key: node)
test.update(for: node, with: anotherNode)
</code>```

The problem is the update doesn't happen.  If I search for newly updated node in the tree, it doesn't exist.

Update

Above code is a modified version of a Red-Black tree, specifically modifying the search method to use a pointer instead.

I've tried my idea on a simplified version of a binary search tree below and it seems to be updating the value of a specified node.

public final class BinaryTree<T: Comparable> {
    public final class Node<T> {
        public var value: T
        public var leftChild: Node<T>?
        public var rightChild: Node<T>?

        public init(value: T, leftChild: Node<T>? = nil, rightChild: Node<T>? = nil) {
            self.value = value
            self.leftChild = leftChild
            self.rightChild = rightChild
        }
    }

    public var rootNode: Node<T>

    public init(rootNode: Node<T>) {
        self.rootNode = rootNode
    }

    public func addNodes(to parent: Node<T>, leftChild: Node<T>?, rightChild: Node<T>?) {
        parent.leftChild = leftChild
        parent.rightChild = rightChild
    }

    public func searchTree(_ value: T, node: inout Node<T>?, f: (inout Node<T>?) -> Void) {
        if node == nil || value == node?.value {
            f(&node)
        } else if value < node!.value {
            searchTree(value, node: &node!.leftChild, f: f)
        } else {
            searchTree(value, node: &node!.rightChild, f: f)
        }
    }
}
```
<p>Tested here.</p>
<pre class="lang-swift prettyprint-override"><code>var rootNode: BinaryTree<Int>.Node<Int>? = BinaryTree<Int>.Node(value: 100, leftChild: nil, rightChild: nil)
let tree = BinaryTree(rootNode: rootNode!)

/// add new nodes. This is not a self-balancing tree so the left child's value has to be smaller than the parent and the right child's value greater than the parent.
let leftChild = BinaryTree<Int>.Node(value: 0, leftChild: nil, rightChild: nil)
let rightChild = BinaryTree<Int>.Node(value: 200, leftChild: nil, rightChild: nil)
tree.addNodes(to: rootNode!, leftChild: leftChild, rightChild: rightChild)

/// the node argument is the starting point of the search so let's start from the root node.
/// the found node will be updated with a new node with a value 50
tree.searchTree(0, node: &rootNode) { foundNode in
    let newNode = BinaryTree<Int>.Node(value: 50, leftChild: nil, rightChild: nil)
    foundNode = newNode
}

/// The node with a value as 0 is now gone.
tree.searchTree(0, node: &rootNode) { foundNode in
    print(foundNode) /// nil
}

/// The node has bee properly updated.
tree.searchTree(50, node: &rootNode) { foundNode in
    print(foundNode) /// node with 50 as the value found
}
</code>```

But can't seem to figure out why the original code isn't updating a node by pointer.

答:
For me the main issue as I mentioned in the comments was with these line of code

```<code>fileprivate(set) var root: Node
    fileprivate let nullLeaf = Node()

    public init() {
        root = nullLeaf
    }
</code>```

Root is currently pointing to a nullLeaf which has the following properties:

```<code>key = nil
leftChild = nil
self.rightChild = nil
self.parent = nil
</code>```

I wasn't sure how your insert function was implemented but when I used my insert implementation, this updated the root's properties to the following:

```<code>key = nil
leftChild = node
self.rightChild = nil
self.parent = nil
</code>```

Now when you run your search function which starts at the root:

```<code>func search(key: T, f: (inout Node) -> Void) {
        search(key: key, node: &root, f:  f)
    }

    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void) {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an
                /// argument to a closure so that it retains the
                /// connection to the node when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }
</code>```

if let nodeKey = node.key { is false based on the above root attributes and so it does go into your block where the logic and completion handler gets executed.

Changes and Implementation

Since your main question to answer is

But can't seem to figure out why the original code isn't updating a
node by pointer.

I am using my insertion implementation of a Binary Search Tree even though you mentioned Binary Tree as the main purpose is to show the pointer working.

Here is what I updated to your code:

TreeNode - no changes to your code

```<code>// No change to your original code
public class TreeNode<T: Comparable>: Equatable {
    public typealias Node = TreeNode<T>

    var key: T?
    var leftChild: Node?
    var rightChild: Node?
    fileprivate weak var parent: Node?

    var isNullLeaf: Bool {
        return key == nil && isLeaf
    }

    var isLeaf: Bool {
        return rightChild == nil && leftChild == nil
    }

    public init(key: T?, leftChild: Node?, rightChild: Node?, parent: Node?) {
        self.key = key
        self.leftChild = leftChild
        self.rightChild = rightChild
        self.parent = parent

        self.leftChild?.parent = self
        self.rightChild?.parent = self
    }

    /// Null leaf
    public convenience init() {
        self.init(key: nil, leftChild: nil, rightChild: nil, parent: nil)
    }

    static public func == <T>(lhs: TreeNode<T>, rhs: TreeNode<T>) -> Bool {
        return lhs.key == rhs.key
    }
}
</code>```

Tree - minor changes and some additions, I have added comments

```<code>public final class Tree<T: Comparable> {
    public typealias Node = TreeNode<T>

    // root starts off as nil
    fileprivate(set) var root: Node?

    // I don't make use of this
    //fileprivate let nullLeaf = Node()

    // No initialization of root
    public init() {
        //root = nullLeaf
    }

    // No change to your code except to safely evaluate root
    func search(key: T, f: (inout Node) -> Void) {
        if var root = root {
            search(key: key, node: &root, f:  f)
        }
    }

    // No change to your code here
    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void)
    {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an argument
                /// to a closure so that it retains the connection to the node
                /// when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }

    // My insert implementation
    public func insert(key: T) {
        if let root = insertInternal(key, currentNode: root)
        {
            self.root = root
        }
    }

    // My insert recursion implementation
    private func insertInternal(_ data: T, currentNode: Node?) -> Node?
    {
        if currentNode == nil
        {
            let newNode = Node()
            newNode.key = data
            return newNode
        }

        if let currentData = currentNode?.key, data > currentData
        {
            currentNode?.rightChild
                = insertInternal(data, currentNode: currentNode?.rightChild)
            return currentNode
        }

        currentNode?.leftChild
            = insertInternal(data, currentNode: currentNode?.leftChild)

        return currentNode
    }

    // My implementation ofLevel order / Breadth first traversal
    // to display values
    func printLevelOrder()
    {
        print("\n** PRINTING BST IN LEVEL ORDER (BFS) ** ")

        var queue: [Node] = []

        if let root = root
        {
            queue.append(root)
        }

        while !queue.isEmpty
        {
            let currentNode = queue.removeFirst()

            if let currentData = currentNode.key
            {
                print(currentData)

                if let left = currentNode.leftChild
                {
                    queue.append(left)
                }

                if let right = currentNode.rightChild
                {
                    queue.append(right)
                }
            }
        }
    }
}
</code>```

Test class - no much changes

```<code>// No change to your code here except display function
class Test<T: Comparable> {
    private(set) var tree = Tree<T>()

    func insert(key: T) {
        tree.insert(key: key)
    }

    func update(for node: T, with newNode: T) {
        tree.search(key: node) { foundNode in
            foundNode.key = newNode
        }
    }

    // Just added a display
    func display() {
        tree.printLevelOrder()
    }
}
</code>```

Finally here is the main

Test 1 - simple with 1 node

```<code>print("Test 1")
var test = Test<Int>()
print("Inserting 10")
test.insert(key: 10)
print("Updating 10 with 8")
test.update(for: 10, with: 8)
test.display()
</code>```

Output

```<code>Test 1
Inserting 10
Updating 10 with 8

** PRINTING BST IN LEVEL ORDER (BFS) **
8
</code>```

As you can see the exchange of values has happened successfully with the pointer

Test 2 - a little more complex tree with many nodes

```<code>print("\n\nTest 2")
test = Test<Int>()
print("Inserting 5")
test.insert(key: 5)
print("Inserting 11")
test.insert(key: 11)
print("Inserting 4")
test.insert(key: 4)
print("Inserting 7")
test.insert(key: 7)
print("Inserting 17")
test.insert(key: 17)
print("Current tree before update")
test.display()
</code>```

This should give us a binary search tree like this:

And printing the BFS traversal shows us this:

```<code>key = nil
leftChild = nil
self.rightChild = nil
self.parent = nil
</code>```0

Now Let's try to change the value of 7 with 16 which is done with the pointer

```<code>key = nil
leftChild = nil
self.rightChild = nil
self.parent = nil
</code>```1

The output is as expected with the value of 7 and swapped with 16

```<code>key = nil
leftChild = nil
self.rightChild = nil
self.parent = nil
</code>```2

Ofcourse, after this swap, the tree is no longer a Binary Search Tree but I think you can see the pointer working well with the above tweaks.

Title: Updating a binary tree using a pointer

Body:
I'm trying to update a self-balancing binary tree.  Normally, you can update it by 1) searching a node, 2) deleting it, 3) and inserting the tree with a new node.  But, I want to see if this is possible simply by retaining a pointer to a node from the first step and updating it so that I can bypass the deletion and insertion and improve the time complexity, especially when it comes to a large number of nodes.

The tree itself is standard binary search tree.

public class TreeNode<T: Comparable>: Equatable {
    public typealias Node = TreeNode<T>

    var key: T?
    var leftChild: Node?
    var rightChild: Node?
    fileprivate weak var parent: Node?

    var isNullLeaf: Bool {
        return key == nil && isLeaf
    }

    var isLeaf: Bool {
        return rightChild == nil && leftChild == nil
    }

    public init(key: T?, leftChild: Node?, rightChild: Node?, parent: Node?) {
        self.key = key
        self.leftChild = leftChild
        self.rightChild = rightChild
        self.parent = parent

        self.leftChild?.parent = self
        self.rightChild?.parent = self
    }

    /// Null leaf
    public convenience init() {
        self.init(key: nil, leftChild: nil, rightChild: nil, parent: nil)
    }

    static public func == <T>(lhs: TreeNode<T>, rhs: TreeNode<T>) -> Bool {
        return lhs.key == rhs.key
    }
}

public final class Tree<T: Comparable> {
    public typealias Node = TreeNode<T>

    fileprivate(set) var root: Node
    fileprivate let nullLeaf = Node()

    public init() {
        root = nullLeaf
    }

    func search(key: T, f: (inout Node) -> Void) {
        search(key: key, node: &root, f:  f)
    }

    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void) {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an argument to a closure so that it retains the connection to the node when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }

    public func insert(key: T) {
       /// insertion logic
    }

    /// Other operations
}

My idea was to search the tree through recursion and when a node is found, pass it as an argument to a closure function, which will ultimately be called to update the node.  Also, the found node would be pass by reference.

class Test<T: Comparable> {
    private(set) var tree = Tree<T>()

    func insert(key: T) {
        tree.insert(key: key)
    }

    func update(for node: T, with newNode: T) {
        tree.search(key: node) { foundNode in
            foundNode.key = newNode
        }
    }
}

let test = Test<MyNode>()
let node = MyNode()
let anotherNode = MyNode()
test.insert(key: node)
test.update(for: node, with: anotherNode)

The problem is the update doesn't happen.  If I search for newly updated node in the tree, it doesn't exist.

Update

Above code is a modified version of a Red-Black tree, specifically modifying the search method to use a pointer instead.

I've tried my idea on a simplified version of a binary search tree below and it seems to be updating the value of a specified node.

public final class BinaryTree<T: Comparable> {
    public final class Node<T> {
        public var value: T
        public var leftChild: Node<T>?
        public var rightChild: Node<T>?

        public init(value: T, leftChild: Node<T>? = nil, rightChild: Node<T>? = nil) {
            self.value = value
            self.leftChild = leftChild
            self.rightChild = rightChild
        }
    }

    public var rootNode: Node<T>

    public init(rootNode: Node<T>) {
        self.rootNode = rootNode
    }

    public func addNodes(to parent: Node<T>, leftChild: Node<T>?, rightChild: Node<T>?) {
        parent.leftChild = leftChild
        parent.rightChild = rightChild
    }

    public func searchTree(_ value: T, node: inout Node<T>?, f: (inout Node<T>?) -> Void) {
        if node == nil || value == node?.value {
            f(&node)
        } else if value < node!.value {
            searchTree(value, node: &node!.leftChild, f: f)
        } else {
            searchTree(value, node: &node!.rightChild, f: f)
        }
    }
}

Tested here.

var rootNode: BinaryTree<Int>.Node<Int>? = BinaryTree<Int>.Node(value: 100, leftChild: nil, rightChild: nil)
let tree = BinaryTree(rootNode: rootNode!)

/// add new nodes. This is not a self-balancing tree so the left child's value has to be smaller than the parent and the right child's value greater than the parent.
let leftChild = BinaryTree<Int>.Node(value: 0, leftChild: nil, rightChild: nil)
let rightChild = BinaryTree<Int>.Node(value: 200, leftChild: nil, rightChild: nil)
tree.addNodes(to: rootNode!, leftChild: leftChild, rightChild: rightChild)

/// the node argument is the starting point of the search so let's start from the root node.
/// the found node will be updated with a new node with a value 50
tree.searchTree(0, node: &rootNode) { foundNode in
    let newNode = BinaryTree<Int>.Node(value: 50, leftChild: nil, rightChild: nil)
    foundNode = newNode
}

/// The node with a value as 0 is now gone.
tree.searchTree(0, node: &rootNode) { foundNode in
    print(foundNode) /// nil
}

/// The node has bee properly updated.
tree.searchTree(50, node: &rootNode) { foundNode in
    print(foundNode) /// node with 50 as the value found
}

But can't seem to figure out why the original code isn't updating a node by pointer.

Body:
For me the main issue as I mentioned in the comments was with these line of code

fileprivate(set) var root: Node
    fileprivate let nullLeaf = Node()

    public init() {
        root = nullLeaf
    }

Root is currently pointing to a nullLeaf which has the following properties:

key = nil
leftChild = nil
self.rightChild = nil
self.parent = nil

I wasn't sure how your insert function was implemented but when I used my insert implementation, this updated the root's properties to the following:

key = nil
leftChild = node
self.rightChild = nil
self.parent = nil

Now when you run your search function which starts at the root:

func search(key: T, f: (inout Node) -> Void) {
        search(key: key, node: &root, f:  f)
    }

    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void) {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an
                /// argument to a closure so that it retains the
                /// connection to the node when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }

if let nodeKey = node.key { is false based on the above root attributes and so it does go into your block where the logic and completion handler gets executed.

Changes and Implementation

Since your main question to answer is

But can't seem to figure out why the original code isn't updating a
node by pointer.

I am using my insertion implementation of a Binary Search Tree even though you mentioned Binary Tree as the main purpose is to show the pointer working.

Here is what I updated to your code:

TreeNode - no changes to your code

// No change to your original code
public class TreeNode<T: Comparable>: Equatable {
    public typealias Node = TreeNode<T>

    var key: T?
    var leftChild: Node?
    var rightChild: Node?
    fileprivate weak var parent: Node?

    var isNullLeaf: Bool {
        return key == nil && isLeaf
    }

    var isLeaf: Bool {
        return rightChild == nil && leftChild == nil
    }

    public init(key: T?, leftChild: Node?, rightChild: Node?, parent: Node?) {
        self.key = key
        self.leftChild = leftChild
        self.rightChild = rightChild
        self.parent = parent

        self.leftChild?.parent = self
        self.rightChild?.parent = self
    }

    /// Null leaf
    public convenience init() {
        self.init(key: nil, leftChild: nil, rightChild: nil, parent: nil)
    }

    static public func == <T>(lhs: TreeNode<T>, rhs: TreeNode<T>) -> Bool {
        return lhs.key == rhs.key
    }
}

Tree - minor changes and some additions, I have added comments

public final class Tree<T: Comparable> {
    public typealias Node = TreeNode<T>

    // root starts off as nil
    fileprivate(set) var root: Node?

    // I don't make use of this
    //fileprivate let nullLeaf = Node()

    // No initialization of root
    public init() {
        //root = nullLeaf
    }

    // No change to your code except to safely evaluate root
    func search(key: T, f: (inout Node) -> Void) {
        if var root = root {
            search(key: key, node: &root, f:  f)
        }
    }

    // No change to your code here
    fileprivate func search(key: T, node: inout Node, f: (inout Node) -> Void)
    {
        if !node.isNullLeaf {
            if let nodeKey = node.key {
                /// When a node is found, pass by reference as an argument
                /// to a closure so that it retains the connection to the node
                /// when it's being update.
                if key == nodeKey {
                    f(&node)
                } else if key < nodeKey {
                    guard node.leftChild != nil else {
                        return
                    }
                    search(key: key, node: &node.leftChild!, f: f)
                } else {
                    guard node.rightChild != nil else {
                        return
                    }
                    search(key: key, node: &node.rightChild!, f: f)
                }
            }
        }
    }

    // My insert implementation
    public func insert(key: T) {
        if let root = insertInternal(key, currentNode: root)
        {
            self.root = root
        }
    }

    // My insert recursion implementation
    private func insertInternal(_ data: T, currentNode: Node?) -> Node?
    {
        if currentNode == nil
        {
            let newNode = Node()
            newNode.key = data
            return newNode
        }

        if let currentData = currentNode?.key, data > currentData
        {
            currentNode?.rightChild
                = insertInternal(data, currentNode: currentNode?.rightChild)
            return currentNode
        }

        currentNode?.leftChild
            = insertInternal(data, currentNode: currentNode?.leftChild)

        return currentNode
    }

    // My implementation ofLevel order / Breadth first traversal
    // to display values
    func printLevelOrder()
    {
        print("\n** PRINTING BST IN LEVEL ORDER (BFS) ** ")

        var queue: [Node] = []

        if let root = root
        {
            queue.append(root)
        }

        while !queue.isEmpty
        {
            let currentNode = queue.removeFirst()

            if let currentData = currentNode.key
            {
                print(currentData)

                if let left = currentNode.leftChild
                {
                    queue.append(left)
                }

                if let right = currentNode.rightChild
                {
                    queue.append(right)
                }
            }
        }
    }
}

Test class - no much changes

// No change to your code here except display function
class Test<T: Comparable> {
    private(set) var tree = Tree<T>()

    func insert(key: T) {
        tree.insert(key: key)
    }

    func update(for node: T, with newNode: T) {
        tree.search(key: node) { foundNode in
            foundNode.key = newNode
        }
    }

    // Just added a display
    func display() {
        tree.printLevelOrder()
    }
}

Finally here is the main

Test 1 - simple with 1 node

print("Test 1")
var test = Test<Int>()
print("Inserting 10")
test.insert(key: 10)
print("Updating 10 with 8")
test.update(for: 10, with: 8)
test.display()

Output

Test 1
Inserting 10
Updating 10 with 8

** PRINTING BST IN LEVEL ORDER (BFS) **
8

As you can see the exchange of values has happened successfully with the pointer

Test 2 - a little more complex tree with many nodes

print("\n\nTest 2")
test = Test<Int>()
print("Inserting 5")
test.insert(key: 5)
print("Inserting 11")
test.insert(key: 11)
print("Inserting 4")
test.insert(key: 4)
print("Inserting 7")
test.insert(key: 7)
print("Inserting 17")
test.insert(key: 17)
print("Current tree before update")
test.display()

This should give us a binary search tree like this:

And printing the BFS traversal shows us this:

Test 2
Inserting 5
Inserting 11
Inserting 4
Inserting 7
Inserting 17
Current tree before update

** PRINTING BST IN LEVEL ORDER (BFS) **
5
4
11
7
17

Now Let's try to change the value of 7 with 16 which is done with the pointer

print("Updating 7 with 16")
test.update(for: 7, with: 16)
print("Current tree after update")
test.display()

The output is as expected with the value of 7 and swapped with 16

Updating 7 with 16
Current tree after update

** PRINTING BST IN LEVEL ORDER (BFS) **
5
4
11
16
17

Ofcourse, after this swap, the tree is no longer a Binary Search Tree but I think you can see the pointer working well with the above tweaks.


来源: stackexchange

问:
No scheduled commands are ready to run | only in $schedule

Laravel Version: 5.7.25

PHP Version: 7.2.14

Database Driver & Version: MySQL 2ª gen. 5.7

Hi, Sorry for the trouble, I have this problem in creating a scheduled command.

Description:

In our crontab -e user we have inserted the following on Debian:

* * * * * cd /var/www/myfolder.com/ && php artisan schedule:run >> crontab.laravel

We have correctly entered the schedule function as follows:

app/console/kernel.php

```<code>  <?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
//        'App\Console\Commands\HelpCenter',
        Commands\HelpCenter::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('elena:help')->everyMinute();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }

}

</code>```

but the result continues to be No scheduled commands are ready to run
we tried all the combinations impossible but nothing.
If we uncomment the function Artisan call working, the script is executed

Try to force command crontab -e

To better understand where the problem lies We have added a crontab directly with the command without going through the schedule as :

* * * * * cd /var/www/myfolder.com/ && php artisan elena:help >> crontab.laravel

This command runs perfectly every minute so we can not figure out where the problem is.
if you have the patience to give us some advice we will be happy. good day

答:
I don't know if I am late, but I have a solution for you.
JUST ADD THE TIMEZONE IN THE SCHEDULE METHOD.
it will start working well.

Example:

```<code>$schedule->command('tenam:before')
        ->dailyAt('22:28')->timezone('Asia/Kolkata');
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Laravel Version: 5.7.25

PHP Version: 7.2.14

Database Driver & Version: MySQL 2ª gen. 5.7

Hi, Sorry for the trouble, I have this problem in creating a scheduled command.

Description:

In our crontab -e user we have inserted the following on Debian:

* * * * * cd /var/www/myfolder.com/ && php artisan schedule:run >> crontab.laravel

We have correctly entered the schedule function as follows:

app/console/kernel.php

  <?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
//        'App\Console\Commands\HelpCenter',
        Commands\HelpCenter::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('elena:help')->everyMinute();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }

}

but the result continues to be No scheduled commands are ready to run
we tried all the combinations impossible but nothing.
If we uncomment the function Artisan call working, the script is executed

Try to force command crontab -e

To better understand where the problem lies We have added a crontab directly with the command without going through the schedule as :

* * * * * cd /var/www/myfolder.com/ && php artisan elena:help >> crontab.laravel

This command runs perfectly every minute so we can not figure out where the problem is.
if you have the patience to give us some advice we will be happy. good day

Body:
I don't know if I am late, but I have a solution for you.
JUST ADD THE TIMEZONE IN THE SCHEDULE METHOD.
it will start working well.

Example:

$schedule->command('tenam:before')
        ->dailyAt('22:28')->timezone('Asia/Kolkata');


问:
Where does ggimage::geom_icon icons come from
I'm trying to insert hockey pucks into my ggplot. On font awesome, I found a hockey puck icon. I was hoping that ggimage::geom_icon could import font awesome icons, but unfortunately it doesn't:

```<code>library(ggimage)

set.seed(2017-02-21)
d <- data.frame(x = rnorm(10),
                y = rnorm(10),
                icon = "hockey-puck")
ggplot(d, aes(x,y)) + geom_icon(aes(image=icon))
</code>```

```<code>Error in download_url(path) :
  Failed to download https://raw.githubusercontent.com/ionic-team/ionicons/master/src/svg/hockey-puck.svg (HTTP 404)
</code>```

Does anyone know where to find icons. I know there is this online vignette, but it doesn't specify where ios-power', 'ios-wifi', 'ios-pie' come from.

答:
the ggimage::list.icon function uses a helper function which looks for png files. This is really not useful, as the icons are svg files. Below a modified version for future users.

list_images <- function (url, filetype = "svg")
{
  x <- readLines(url)
  y <- x[grep(paste0("title=\"[a-zA-Z0-9\\-]+\\.", filetype), x)]
  sub(paste0(".*title=\"([a-zA-Z0-9\\-]+)\\.",filetype, ".*"), "\\1", y)
}

list_icon <- function(){
  list_images("https://github.com/ionic-team/ionicons/tree/master/src/svg")
}

head(list_icon(), 10)
#>  [1] "accessibility-outline" "accessibility-sharp"   "accessibility"
#>  [4] "add-circle-outline"    "add-circle-sharp"      "add-circle"
#>  [7] "add-outline"           "add-sharp"             "add"
#> [10] "airplane-outline"
```

Body:
I'm trying to insert hockey pucks into my ggplot. On font awesome, I found a hockey puck icon. I was hoping that ggimage::geom_icon could import font awesome icons, but unfortunately it doesn't:

library(ggimage)

set.seed(2017-02-21)
d <- data.frame(x = rnorm(10),
                y = rnorm(10),
                icon = "hockey-puck")
ggplot(d, aes(x,y)) + geom_icon(aes(image=icon))

Error in download_url(path) :
  Failed to download https://raw.githubusercontent.com/ionic-team/ionicons/master/src/svg/hockey-puck.svg (HTTP 404)

Does anyone know where to find icons. I know there is this online vignette, but it doesn't specify where ios-power', 'ios-wifi', 'ios-pie' come from.


问:
Is it possible to replace a value in a json string that occurs multiple times only at the top level of the structure via regex?
Hiho,

I have a json string with the following structure:

```<code>{
   "version": "1.0.0",
   "dependencies": {
      "version": "1.0.0"
   }
}
</code>```

It can also look like this:

```<code>{
   "dependencies": {
      "version": "1.0.0"
   },
   "version": "1.0.0"
}
</code>```

Or like this:

```<code>{ "version": "1.0.0", "dependencies": { "version": "1.0.0" } }
</code>```

Or like this:

```<code>{ "dependencies": { "version": "1.0.0" }, "version": "1.0.0" }
</code>```

As can be seen, the string contains 2 times the name "version" with the value "1.0.0". One time on 'top' level of the json structure, and one time one level deeper.

Before/behind the name "version" can be other name/value pairs.

The name "version" can occur only 1 time on top level.

The name "version" can occur multiple times in deeper levels.

Now I want to replace the value "1.0.0" with another value, but only the top level value! I tried to define a regular expression for this, but failed so far.

I'm starting to wonder if it's even possible to define such an expression. The underlying problem seems to be that the first hit of the name is not necessarily the top-level key (see examples 2 and 4).

It would be really nice if someone could help me! :)

答:
This may not work depending on your Java version (that's the tag you used) as it requires the use of non-fixed width Lookaheads and Lookbehinds, but this regex should be usable in later versions of Java or JavaScript.

```<code>(?:(?<!(?:[\s\S]*\{[\s\S]*){2,})(?<="version" *: *")([\d\.]*)(?=")|(?<="version" *: *")([\d\.]*)(?=")(?!(?:[\s\S]*\}[\s\S]*){2,}))
</code>```

You can test it by yourself and see how it works in the following link: https://regex101.com/r/6Q3KXQ/1

Body:
Hiho,

I have a json string with the following structure:

{
   "version": "1.0.0",
   "dependencies": {
      "version": "1.0.0"
   }
}

It can also look like this:

{
   "dependencies": {
      "version": "1.0.0"
   },
   "version": "1.0.0"
}

Or like this:

{ "version": "1.0.0", "dependencies": { "version": "1.0.0" } }

Or like this:

{ "dependencies": { "version": "1.0.0" }, "version": "1.0.0" }

As can be seen, the string contains 2 times the name "version" with the value "1.0.0". One time on 'top' level of the json structure, and one time one level deeper.

Before/behind the name "version" can be other name/value pairs.

The name "version" can occur only 1 time on top level.

The name "version" can occur multiple times in deeper levels.

Now I want to replace the value "1.0.0" with another value, but only the top level value! I tried to define a regular expression for this, but failed so far.

I'm starting to wonder if it's even possible to define such an expression. The underlying problem seems to be that the first hit of the name is not necessarily the top-level key (see examples 2 and 4).

It would be really nice if someone could help me! :)

Body:
This may not work depending on your Java version (that's the tag you used) as it requires the use of non-fixed width Lookaheads and Lookbehinds, but this regex should be usable in later versions of Java or JavaScript.

(?:(?<!(?:[\s\S]*\{[\s\S]*){2,})(?<="version" *: *")([\d\.]*)(?=")|(?<="version" *: *")([\d\.]*)(?=")(?!(?:[\s\S]*\}[\s\S]*){2,}))

You can test it by yourself and see how it works in the following link: https://regex101.com/r/6Q3KXQ/1


问:
msb4018: the "createvirtualdirectory" task failed unexpectedly
While deploying Biztalk application I am getting below error:

\Program Files (x86)---- for BizTalk 1.0.0\1.0\Deployment\Framework\BizTalkDeploymentFramework.targets(1829,5): error MSB4018: The "CreateVirtualDirectory" task failed unexpectedly.\r
C:\Program Files (x86)-----for BizTalk 1.0.0\1.0\Deployment\Framework\BizTalkDeploymentFramework.targets(1829,5): error MSB4018: System.Runtime.InteropServices.COMException (0x80070003): The system cannot find the path specified.\r
C:\Program Files (x86)----- for BizTalk 1.0.0\1.0\Deployment\Framework\BizTalkDeploymentFramework.targets(1829,5): error MSB4018: \r

答:
"COMException (0x80070003): The system cannot find the path specified."

Since this is happening during app deployment via an MSI generated with the Deployment Framework, it appears that the physical folder for the virtual directory does not exist. Maybe it is not being packaged in the MSI at all, or maybe the location is different than the one specified in the .btdfproj.

I suggest you review the IIS sample application included with the Framework.


问:
'mat-label' is not a known element Error in latest Angular Material
I got an error in my Angular Material:

```<code>compiler.js:466 Uncaught Error: Template parse errors:
'mat-label' is not a known element:
1. If 'mat-label' is an Angular component, then verify that it is part of this module.
2. If 'mat-label' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
        </mat-form-field>
        <mat-form-field>
            [ERROR ->]<mat-label>Both a label and a placeholder</mat-label>
            <input matInput placeholder="Simple"):
</code>```

Question:

Material Label is under MatFormFieldModule Here's the link

Now, what is the possible cause of the issue why Mat-Label is unknown to Angular Material.

Here is the HTML

```<code><mat-form-field>
          <mat-label>Both a label and a placeholder</mat-label>
          <input matInput placeholder="Simple placeholder">
</mat-form-field>
</code>```

答: Could also be that you forgot to add your component in your module (that is already importing MatFormFieldModule and MatInputModule.

ContentLicense: CC BY-SA 3.0

Body:
I got an error in my Angular Material:

compiler.js:466 Uncaught Error: Template parse errors:
'mat-label' is not a known element:
1. If 'mat-label' is an Angular component, then verify that it is part of this module.
2. If 'mat-label' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
        </mat-form-field>
        <mat-form-field>
            [ERROR ->]<mat-label>Both a label and a placeholder</mat-label>
            <input matInput placeholder="Simple"):

Question:

Material Label is under MatFormFieldModule Here's the link

Now, what is the possible cause of the issue why Mat-Label is unknown to Angular Material.

Here is the HTML

<mat-form-field>
          <mat-label>Both a label and a placeholder</mat-label>
          <input matInput placeholder="Simple placeholder">
</mat-form-field>


问:
Typescript: Typing Function Return Type based on Parameters
I was wondering if there is way to type the return of a function based on the input given to it. Here is an example of what I am thinking:

```<code>function toEnum(...strings: string[]) {
  const enumObject = {};

  strings.forEach((str) => {
    enumObject[str.toUpperCase()] = str;
  });

  return enumObject;
}

const myEnum = toEnum('one', 'two', 'three')
</code>```

Is there a way to type this function so that we know that myEnum looks like:

```<code>{
  ONE: 'one',
  TWO: 'two',
  THREE: 'three'
}
</code>```

edit:

as @dariosicily mentioned, we could type enumObject using a Record<string, string> or index signatures, but I am wondering if there is a way to know the actual keys present in the return object based on the params passed in.

答:
The problem is due to the fact that while in the javascript language the line enumObject[str.toUpperCase()] = str; assignment is legitimate with typescript the same line causes an error because you have not explicitely declared the index signature of the enumObject or explicitely declared it as any.

In this cases one way to solve the issue is use the builtin Record utility type applying it to your enumObject like below:

```<code>function toEnum(...strings: string[]) {
    const enumObject: Record<string, string> = {};
    strings.forEach((str) => {
        enumObject[str.toUpperCase()] = str;
    });
    return enumObject;
}

const myEnum = toEnum('one', 'two', 'three')
//it will print { ONE: 'one', TWO: 'two', THREE: 'three' }
console.log(myEnum);
</code>```

Edit: answering to the question

there is a way to know the actual keys present in the return object
based on the params passed in

You can use the Object.keys method and return the keys as an Array<string>:

```<code>const myEnum = toEnum('one', 'two', 'three')
//it will print [ONE, TWO, THREE]
const keys = (Object.keys(myEnum) as Array<string>);
</code>```

If you want to create a new type from keys you can use typeof:

```<code>const keys = (Object.keys(myEnum) as Array<string>);
//type KeysType = 'ONE' | 'TWO' | 'THREE'
type KeysType = typeof keys[number];
</code>```

Body:
I was wondering if there is way to type the return of a function based on the input given to it. Here is an example of what I am thinking:

function toEnum(...strings: string[]) {
  const enumObject = {};

  strings.forEach((str) => {
    enumObject[str.toUpperCase()] = str;
  });

  return enumObject;
}

const myEnum = toEnum('one', 'two', 'three')

Is there a way to type this function so that we know that myEnum looks like:

{
  ONE: 'one',
  TWO: 'two',
  THREE: 'three'
}

edit:

as @dariosicily mentioned, we could type enumObject using a Record<string, string> or index signatures, but I am wondering if there is a way to know the actual keys present in the return object based on the params passed in.

Body:
The problem is due to the fact that while in the javascript language the line enumObject[str.toUpperCase()] = str; assignment is legitimate with typescript the same line causes an error because you have not explicitely declared the index signature of the enumObject or explicitely declared it as any.

In this cases one way to solve the issue is use the builtin Record utility type applying it to your enumObject like below:

function toEnum(...strings: string[]) {
    const enumObject: Record<string, string> = {};
    strings.forEach((str) => {
        enumObject[str.toUpperCase()] = str;
    });
    return enumObject;
}

const myEnum = toEnum('one', 'two', 'three')
//it will print { ONE: 'one', TWO: 'two', THREE: 'three' }
console.log(myEnum);

Edit: answering to the question

there is a way to know the actual keys present in the return object
based on the params passed in

You can use the Object.keys method and return the keys as an Array<string>:

const myEnum = toEnum('one', 'two', 'three')
//it will print [ONE, TWO, THREE]
const keys = (Object.keys(myEnum) as Array<string>);

If you want to create a new type from keys you can use typeof:

const keys = (Object.keys(myEnum) as Array<string>);
//type KeysType = 'ONE' | 'TWO' | 'THREE'
type KeysType = typeof keys[number];


问:
How to rotate a character by 90 degrees in python?
I'm trying to rotate the character | sideways by 90 degrees, think of a longer - and then print it.

would appreciate the help as to how I can do that?

答:
For converting '|' char to 90 degree, we can replace with  all chars '|' to  '—'  chars.

s1 = "Example | text | with | horizontal | string"

def RotateCharacter90(s1):
    s2 = s1.replace( "|", "—")
    return s2

print(RotateCharacter90(s1))

""" OUTPUT: Example — text — with — horizontal — string """
```


问:
How to correct the constructor?
```<code>using System;
using System.Text;
using System.Collections.Generic;

class RGB: IEquatable<RGB> {
  private byte R, G, B;

  public static RGB Red   = new(255, 0, 0);
  public static RGB Green = new(0, 255, 0);
  public static RGB Blue  = new(0, 0, 255);

  public RGB(byte R, byte G, byte B) {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public RGB(string color_hexcode){
    byte[] red_bytes   = Encoding.UTF8.GetBytes(color_hexcode[1..3]);
    byte[] green_bytes = Encoding.UTF8.GetBytes(color_hexcode[3..5]);
    byte[] blue_bytes  = Encoding.UTF8.GetBytes(color_hexcode[5..]);

    this.R = Convert.ToByte(Convert.ToHexString(red_bytes));
    this.G = Convert.ToByte(Convert.ToHexString(green_bytes));
    this.B = Convert.ToByte(Convert.ToHexString(blue_bytes));
  }

  public byte RedValue   { get => this.R; }
  public byte GreenValue { get => this.G; }
  public byte BlueValue  { get => this.B; }

  public bool ContainsRed   { get => this.R != 0  ? true : false; }
  public bool ContainsGreen { get => this.G != 0  ? true : false; }
  public bool ContainsBlue  { get => this.B != 0  ? true : false; }

  public bool Equals(RGB other) {
    return (this.R, this.G, this.B) == (other.R, other.G, other.B);
  }
}

class Program {
  public static void Main (string[] args) {
    RGB Yellow = new("#ffff00");
    Console.WriteLine(Yellow.ContainsBlue);
  }
}
</code>```

My code causes to:
Unhandled exception. System.OverflowException: Value was either too large or too small for an unsigned byte. at public RGB(string color_hexcode)....

I tried to convert the string to hexstring then the hexstring to byte. #ff is equal to decimal 255. So #ff is in bounds of byte data type. I don't get what's wrong with this code. C# must be convert #ff to byte seamlessly. Does anyone have any idea how to fix it?

答:
Assuming your color_hexcode is a string like #ffeecc it'd be like this:

```<code>  public RGB(string color_hexcode){

    this.R = byte.Parse(color_hexcode[1..3], NumberStyles.HexNumber);
    this.G = byte.Parse(color_hexcode[3..5], NumberStyles.HexNumber);
    this.B = byte.Parse(color_hexcode[5..7], NumberStyles.HexNumber);
  }
</code>```

As for why your attempt blew up:

Encoding.UTF8.GetBytes() will take a string like "ff" and return the bytes that make up those chars. f is 99 or 0x63

This means it gives you a new byte[] {0x63, 0x63}

Convert.ToHexString on this gives you "6363"

Convert.ToByte on "6363" blows up because no matter which way you cut it, be it 6363 or 0x6363 it's bigger than a byte

Title: How to correct the constructor?

Body:
using System;
using System.Text;
using System.Collections.Generic;

class RGB: IEquatable<RGB> {
  private byte R, G, B;

  public static RGB Red   = new(255, 0, 0);
  public static RGB Green = new(0, 255, 0);
  public static RGB Blue  = new(0, 0, 255);

  public RGB(byte R, byte G, byte B) {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public RGB(string color_hexcode){
    byte[] red_bytes   = Encoding.UTF8.GetBytes(color_hexcode[1..3]);
    byte[] green_bytes = Encoding.UTF8.GetBytes(color_hexcode[3..5]);
    byte[] blue_bytes  = Encoding.UTF8.GetBytes(color_hexcode[5..]);

    this.R = Convert.ToByte(Convert.ToHexString(red_bytes));
    this.G = Convert.ToByte(Convert.ToHexString(green_bytes));
    this.B = Convert.ToByte(Convert.ToHexString(blue_bytes));
  }

  public byte RedValue   { get => this.R; }
  public byte GreenValue { get => this.G; }
  public byte BlueValue  { get => this.B; }

  public bool ContainsRed   { get => this.R != 0  ? true : false; }
  public bool ContainsGreen { get => this.G != 0  ? true : false; }
  public bool ContainsBlue  { get => this.B != 0  ? true : false; }

  public bool Equals(RGB other) {
    return (this.R, this.G, this.B) == (other.R, other.G, other.B);
  }
}

class Program {
  public static void Main (string[] args) {
    RGB Yellow = new("#ffff00");
    Console.WriteLine(Yellow.ContainsBlue);
  }
}

My code causes to:
Unhandled exception. System.OverflowException: Value was either too large or too small for an unsigned byte. at public RGB(string color_hexcode)....

I tried to convert the string to hexstring then the hexstring to byte. #ff is equal to decimal 255. So #ff is in bounds of byte data type. I don't get what's wrong with this code. C# must be convert #ff to byte seamlessly. Does anyone have any idea how to fix it?

Body:
Assuming your color_hexcode is a string like #ffeecc it'd be like this:

  public RGB(string color_hexcode){

    this.R = byte.Parse(color_hexcode[1..3], NumberStyles.HexNumber);
    this.G = byte.Parse(color_hexcode[3..5], NumberStyles.HexNumber);
    this.B = byte.Parse(color_hexcode[5..7], NumberStyles.HexNumber);
  }

As for why your attempt blew up:

Encoding.UTF8.GetBytes() will take a string like "ff" and return the bytes that make up those chars. f is 99 or 0x63

This means it gives you a new byte[] {0x63, 0x63}

Convert.ToHexString on this gives you "6363"

Convert.ToByte on "6363" blows up because no matter which way you cut it, be it 6363 or 0x6363 it's bigger than a byte


问:
File not found Jupyter notebook
I am having trouble loading a file in jupyter notebook.

Here is my project tree:

-- home

---- cdsw

------ my_main.py

------ notebooks

-------- my_notebook.ipynb

------ dns

-------- assets

---------- stopwords.txt

-------- bilans

---------- my_module.py

Know that '/home/cdsw/" is in my PYTHONPATH - the same interpreter in which I launch jupyter -.

In my_module.py I have these lines:

```<code>PATH_STOPWORDS: Final = os.path.join("dns", "assets", "stopwords.txt")
STOPWORDS: Final = load_stopwords(PATH_STOPWORDS)
</code>```

load_stopwords is basically just a open(PATH_STOPWORDS, 'r').
So my problem is that when I import dns.bilans.my_module inside my_main.py it works fine: file is correctly loaded.
Yet, when I import it from my_notebook.ipynb, it does not :

```<code>FileNotFoundError: [Errno 2] No such file or directory: 'dns/assets/stopwords.txt'
</code>```

So my_module is indeed founded by jupyter kernel (because it reads the code lines of the file) but can't use the relative path provided like it does from a run in a terminal.

When I use a open(relpath, 'r') inside a module, I don't need to go all through the project tree right ? Indeed it DOES work in my_main.py ...

I really don't get it ...

The output of os.getcwd() in jupyter is "/home/cdsw/notebooks".

答:
This existing SO question suggests how to find files relative to the position of a Python code file.  It isn't exactly the same question, however, and I believe that this technique is so important for every Python programmer to understand, that I'm going to provide a more thorough answer.

Given a piece of Python code, one can compute the path of the directory of the source file containing that code via:

```<code>here = os.path.dirname(__file__)
</code>```

Having the position of the relevant source file, it is easy to compute an absolute path to any data file that has a well known location relative to that source file.  In this case, the way to do that is:

```<code>stopwords_path = os.path.join(here, '..', '..', 'assets', 'stopwords.txt')
</code>```

This path can be supplied to open() or used in any other way to refer to the stopwords.txt data file.  Here, the way to use this path would be:

```<code>load_stopwords(stopwords_path)
</code>```

I use this technique to not only find files that accompany code in a particular module, but also to find files that are in other locations throughout my source tree.  As long as the code and data file exist in the same source repository, or are shipped together in a single Python package, the relative path will not change from installation to installation, and so this technique will work.

In general, you should avoid the use of relative paths.  Whenever possible, you should also avoid having to tell your code where to find something.  For any situation, ask yourself how you can obtain a reliable absolute path that you can then use to then locate whatever it is you're wanting to access.

Title: File not found Jupyter notebook

Body:
I am having trouble loading a file in jupyter notebook.

Here is my project tree:

-- home

---- cdsw

------ my_main.py

------ notebooks

-------- my_notebook.ipynb

------ dns

-------- assets

---------- stopwords.txt

-------- bilans

---------- my_module.py

Know that '/home/cdsw/" is in my PYTHONPATH - the same interpreter in which I launch jupyter -.

In my_module.py I have these lines:

PATH_STOPWORDS: Final = os.path.join("dns", "assets", "stopwords.txt")
STOPWORDS: Final = load_stopwords(PATH_STOPWORDS)

load_stopwords is basically just a open(PATH_STOPWORDS, 'r').
So my problem is that when I import dns.bilans.my_module inside my_main.py it works fine: file is correctly loaded.
Yet, when I import it from my_notebook.ipynb, it does not :

FileNotFoundError: [Errno 2] No such file or directory: 'dns/assets/stopwords.txt'

So my_module is indeed founded by jupyter kernel (because it reads the code lines of the file) but can't use the relative path provided like it does from a run in a terminal.

When I use a open(relpath, 'r') inside a module, I don't need to go all through the project tree right ? Indeed it DOES work in my_main.py ...

I really don't get it ...

The output of os.getcwd() in jupyter is "/home/cdsw/notebooks".

Body:
This existing SO question suggests how to find files relative to the position of a Python code file.  It isn't exactly the same question, however, and I believe that this technique is so important for every Python programmer to understand, that I'm going to provide a more thorough answer.

Given a piece of Python code, one can compute the path of the directory of the source file containing that code via:

here = os.path.dirname(__file__)

Having the position of the relevant source file, it is easy to compute an absolute path to any data file that has a well known location relative to that source file.  In this case, the way to do that is:

stopwords_path = os.path.join(here, '..', '..', 'assets', 'stopwords.txt')

This path can be supplied to open() or used in any other way to refer to the stopwords.txt data file.  Here, the way to use this path would be:

load_stopwords(stopwords_path)

I use this technique to not only find files that accompany code in a particular module, but also to find files that are in other locations throughout my source tree.  As long as the code and data file exist in the same source repository, or are shipped together in a single Python package, the relative path will not change from installation to installation, and so this technique will work.

In general, you should avoid the use of relative paths.  Whenever possible, you should also avoid having to tell your code where to find something.  For any situation, ask yourself how you can obtain a reliable absolute path that you can then use to then locate whatever it is you're wanting to access.


问:
FileStream Constructors in ASP.NET Core
In ASP.NET, we can achieve this by FileStream.FileStream(string path, FileMode mode, FileAccess access); as below:

```<code>public class LoginController : MMBaseController
{
    [AllowAnonymous]
    public ActionResult Home(string returnUrl){
        var fileStream = new FileStream(Server.MapPath("~/key.crt"), FileMode.Open, FileAccess.Read);
        string text;
        using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
        {
            text = streamReader.ReadToEnd();
        }
        Response response = new Response(text, samlTmp);
    }
}

public class MMBaseController : Controller
{
    //Controller for SignIn, SignOut, OnException, Dispose etc..
}
</code>```

I tried below code:

```<code>[AllowAnonymous]
public ActionResult Home(string returnUrl, [FromService] IWebHostEnvironment environment)
{
    var fileStream = System.IO.File.Open(environment.ContentRootFileProvider.GetFileInfo("/key.crt").PhysicalPath, FileMode.Open, FileAccess.Read);
    string text;
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
    {
        text = streamReader.ReadToEnd();
    }
}
</code>```

But it is showing:

The type or namespace name 'FromService' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'FromServiceAttribute' could not be found (are you missing a using directive or an assembly reference?)

Can we achieve same in .NET Core? I need to pass file path and specify file mode along with the file read/write permission.

I have tried File.Open(). But I get this error even after adding the namespace using System.IO;

The name 'Server' does not exist in the current context

答:
Use System.IO.File.Open(path, FileMode, FileAccess) instead

https://learn.microsoft.com/fr-fr/dotnet/api/system.io.file.open?view=net-6.0#system-io-file-open(system-string-system-io-filemode-system-io-fileaccess)

```<code>var fileStream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read);
</code>```

Title: FileStream Constructors in ASP.NET Core

Body:
In ASP.NET, we can achieve this by FileStream.FileStream(string path, FileMode mode, FileAccess access); as below:

public class LoginController : MMBaseController
{
    [AllowAnonymous]
    public ActionResult Home(string returnUrl){
        var fileStream = new FileStream(Server.MapPath("~/key.crt"), FileMode.Open, FileAccess.Read);
        string text;
        using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
        {
            text = streamReader.ReadToEnd();
        }
        Response response = new Response(text, samlTmp);
    }
}

public class MMBaseController : Controller
{
    //Controller for SignIn, SignOut, OnException, Dispose etc..
}

I tried below code:

[AllowAnonymous]
public ActionResult Home(string returnUrl, [FromService] IWebHostEnvironment environment)
{
    var fileStream = System.IO.File.Open(environment.ContentRootFileProvider.GetFileInfo("/key.crt").PhysicalPath, FileMode.Open, FileAccess.Read);
    string text;
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
    {
        text = streamReader.ReadToEnd();
    }
}

But it is showing:

The type or namespace name 'FromService' could not be found (are you missing a using directive or an assembly reference?)

The type or namespace name 'FromServiceAttribute' could not be found (are you missing a using directive or an assembly reference?)

Can we achieve same in .NET Core? I need to pass file path and specify file mode along with the file read/write permission.

I have tried File.Open(). But I get this error even after adding the namespace using System.IO;

The name 'Server' does not exist in the current context

Body:
Use System.IO.File.Open(path, FileMode, FileAccess) instead

https://learn.microsoft.com/fr-fr/dotnet/api/system.io.file.open?view=net-6.0#system-io-file-open(system-string-system-io-filemode-system-io-fileaccess)

var fileStream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read);


问:
Automatically not insert created_at and updated_at in laravel not working
Automatically not insert created_at and updated_at in laravel not working.

```<code>DB::table('commundityvendordata')->insert($commdata);
</code>```

I am using this above statement passing an array for inserting multiple record $commdataworking fine but when check my created_at and updated_at column in database not getting timestamp.

Model:

```<code><?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class commundityvendordata extends Model
{
    use HasFactory;
    protected $table ='commundityvendordata';
}
</code>```

Migration:

```<code>public function up()
    {
        Schema::create('commundityvendordata', function (Blueprint $table) {
            $table->bigIncrements('vender_id')->unsignedBigInteger();
            $table->date('new_date');
            $table->unsignedBigInteger('cd_id');
            $table->foreign('cd_id')->references('cd_id')->on('communitydata')->onDelete('cascade');
            $table->unsignedBigInteger('cn_id');
            $table->foreign('cn_id')->references('cd_id')->on('communitydata')->onDelete('cascade');
            $table->unsignedBigInteger('unit_id');
            $table->foreign('unit_id')->references('unit_id')->on('units')->onDelete('cascade');
            $table->unsignedInteger('vender1');
            $table->unsignedInteger('vender2');
            $table->unsignedInteger('vender3');
            $table->unsignedInteger('vender4');
            $table->timestamps();
        });
    }
</code>```

Controller:

```<code>function commundityvendordata(Request $request){
                $collection = count(collect($request));
                $cvendordata = new commundityvendordata;
                for ($i=0; $i < $collection; $i++) {
                $new_date = Carbon::parse($request->new_date)->format('Y-m-d');
                $CCode=communitydata::where('c_code','=',$request->ccode[$i])->first();
                $cd_id = $CCode['cd_id'];
                $CName=communitydata::where('c_name','=',$request->cname[$i])->first();
                $cn_id = $CName['cd_id'];
                $CUnit=units::where('unit','=',$request->cunit[$i])->first();
                $unit_id = $CUnit['unit_id'];
                $vender1 = $request->vendor1[$i];
                $vender2 = $request->vendor2[$i];
                $vender3 = $request->vendor3[$i];
                $vender4 = $request->vendor4[$i];
                   $commdata = [
                    'new_date'  => $new_date,
                    'cd_id'     => $cd_id,
                    'cn_id'     => $cn_id,
                    'unit_id'   => $unit_id,
                    'vender1'   => $vender1,
                    'vender2'   => $vender2,
                    'vender3'   => $vender3,
                    'vender4'   => $vender4
                ];
                if($cd_id != ''){
                         DB::table('commundityvendordata')->insert($commdata);
                    }else{
                        return back()->with('success','Data Saved...');
                    }
            }
    }
</code>```

database table screen shot:

答:
This is because you haven't set the default value for created_at and updated_at. For doing so, you can following 2-3 solutions:

Solution 1

Go to phpmyadmin

Select Database table. (In your case, it's commundityvendordata)

Then go to structure and set the default value for created_at and updated_at

And for updated_at, you can set the Attribute to on update Current_Timestamp

Solution 2

In your commdata array, just add the created_at and updated_at

```<code>$commdata = [
             ...
             'created_at' => date("Y-m-d h:i:s"),
             'updated_at' => date("Y-m-d h:i:s"),
             ];
</code>```

Solution 3

Is to make changes in your Scheme"

```<code>Schema::create('commundityvendordata', function (Blueprint $table) {
          $table->timestamps('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
          $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
        });
}
</code>```

Body:
Automatically not insert created_at and updated_at in laravel not working.

DB::table('commundityvendordata')->insert($commdata);

I am using this above statement passing an array for inserting multiple record $commdataworking fine but when check my created_at and updated_at column in database not getting timestamp.

Model:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class commundityvendordata extends Model
{
    use HasFactory;
    protected $table ='commundityvendordata';
}

Migration:

public function up()
    {
        Schema::create('commundityvendordata', function (Blueprint $table) {
            $table->bigIncrements('vender_id')->unsignedBigInteger();
            $table->date('new_date');
            $table->unsignedBigInteger('cd_id');
            $table->foreign('cd_id')->references('cd_id')->on('communitydata')->onDelete('cascade');
            $table->unsignedBigInteger('cn_id');
            $table->foreign('cn_id')->references('cd_id')->on('communitydata')->onDelete('cascade');
            $table->unsignedBigInteger('unit_id');
            $table->foreign('unit_id')->references('unit_id')->on('units')->onDelete('cascade');
            $table->unsignedInteger('vender1');
            $table->unsignedInteger('vender2');
            $table->unsignedInteger('vender3');
            $table->unsignedInteger('vender4');
            $table->timestamps();
        });
    }

Controller:

function commundityvendordata(Request $request){
                $collection = count(collect($request));
                $cvendordata = new commundityvendordata;
                for ($i=0; $i < $collection; $i++) {
                $new_date = Carbon::parse($request->new_date)->format('Y-m-d');
                $CCode=communitydata::where('c_code','=',$request->ccode[$i])->first();
                $cd_id = $CCode['cd_id'];
                $CName=communitydata::where('c_name','=',$request->cname[$i])->first();
                $cn_id = $CName['cd_id'];
                $CUnit=units::where('unit','=',$request->cunit[$i])->first();
                $unit_id = $CUnit['unit_id'];
                $vender1 = $request->vendor1[$i];
                $vender2 = $request->vendor2[$i];
                $vender3 = $request->vendor3[$i];
                $vender4 = $request->vendor4[$i];
                   $commdata = [
                    'new_date'  => $new_date,
                    'cd_id'     => $cd_id,
                    'cn_id'     => $cn_id,
                    'unit_id'   => $unit_id,
                    'vender1'   => $vender1,
                    'vender2'   => $vender2,
                    'vender3'   => $vender3,
                    'vender4'   => $vender4
                ];
                if($cd_id != ''){
                         DB::table('commundityvendordata')->insert($commdata);
                    }else{
                        return back()->with('success','Data Saved...');
                    }
            }
    }

database table screen shot:

Body:
This is because you haven't set the default value for created_at and updated_at. For doing so, you can following 2-3 solutions:

Solution 1

Go to phpmyadmin

Select Database table. (In your case, it's commundityvendordata)

Then go to structure and set the default value for created_at and updated_at

And for updated_at, you can set the Attribute to on update Current_Timestamp

Solution 2

In your commdata array, just add the created_at and updated_at

$commdata = [
             ...
             'created_at' => date("Y-m-d h:i:s"),
             'updated_at' => date("Y-m-d h:i:s"),
             ];

Solution 3

Is to make changes in your Scheme"

Schema::create('commundityvendordata', function (Blueprint $table) {
          $table->timestamps('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
          $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
        });
}


问:
Google Map in flutter not showing markers
I am trying to implete the Google Maps  Marker Functionality for my app. By using the Co-ordinates.

It works fine. But the markers/pointers not  shown in the map. only empty map is render on full screen

Any ways to Solve this issue ??

Full Code

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapScreen extends StatefulWidget {
  const GoogleMapScreen({Key? key}) : super(key: key);

  @override
  _GoogleMapScreenState createState() => _GoogleMapScreenState();
}

class _GoogleMapScreenState extends State<GoogleMapScreen> {
  late GoogleMapController mapController;
  Set<Marker> markers = {};

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void onMapcreated(GoogleMapController controller) {
    setState(() {
      markers.add(const Marker(
        markerId: MarkerId('1'),
        position: LatLng(13.007488, 77.598656),
        infoWindow: InfoWindow(
          title: 'Marker Title Second ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('2'),
        position: LatLng(12.999595, 77.585856),
        infoWindow: InfoWindow(
          title: 'Marker Title Third ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('3'),
        position: LatLng(13.001916, 77.588849),
        infoWindow: InfoWindow(
          title: 'Marker Title Fourth ',
          snippet: 'My Custom Subtitle',
        ),
      ));
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: GoogleMap(
          initialCameraPosition: const CameraPosition(
            target: LatLng(36.736847, 4.045026),
            zoom: 15,
          ),
          mapToolbarEnabled: true,
          buildingsEnabled: false,
          myLocationButtonEnabled: true,
          mapType: MapType.normal,
          markers: markers,
          onMapCreated: onMapcreated,
        ),
      ),
    );
  }
}

```

Output

I used the Empty API key for Google API.

And also I need to hide the plus, minus symbol & copyrights from the map

答:
You need to have Google Map API Key Otherwise you'll see an empty white screen.

I tried your code only machine with google api key and it's working fine.
here is the code I've used(try to copy paste and check)

2.for hiding zoom button use zoomControlsEnabled: true,

```<code>import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapScreen extends StatefulWidget {
  const GoogleMapScreen({Key? key}) : super(key: key);

  @override
  _GoogleMapScreenState createState() => _GoogleMapScreenState();
}

class _GoogleMapScreenState extends State<GoogleMapScreen> {
  late GoogleMapController mapController;
  Set<Marker> markers = {};

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void onMapcreated(GoogleMapController controller) {
    setState(() {
      markers.add(const Marker(
        markerId: MarkerId('1'),
        position: LatLng(13.007488, 77.598656),
        infoWindow: InfoWindow(
          title: 'Marker Title Second ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('2'),
        position: LatLng(13.007481, 77.598651),
        infoWindow: InfoWindow(
          title: 'Marker Title Third ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('3'),
        position: LatLng(13.001916, 77.588849),
        infoWindow: InfoWindow(
          title: 'Marker Title Fourth ',
          snippet: 'My Custom Subtitle',
        ),
      ));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: GoogleMap(
          initialCameraPosition: const CameraPosition(
            target: LatLng(13.007481, 77.598656),
            zoom: 10,
          ),
          mapToolbarEnabled: true,
          buildingsEnabled: false,
          myLocationButtonEnabled: true,
          mapType: MapType.normal,
          markers: markers,
          onMapCreated: onMapcreated,
          zoomControlsEnabled: true,
        ),
      ),
    );
  }
}
</code>```

Note:
I guess the problem was that your target LatLng was referring to the
different location and another reason could be that you didn’t
provided API key.

your earlier targer was 36.736847, 4.045026 to which i changed to 13.007488, 77.598656 nearest to your marker, including your zoom value from 15 to 10

Body:
I am trying to implete the Google Maps  Marker Functionality for my app. By using the Co-ordinates.

It works fine. But the markers/pointers not  shown in the map. only empty map is render on full screen

Any ways to Solve this issue ??

Full Code

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapScreen extends StatefulWidget {
  const GoogleMapScreen({Key? key}) : super(key: key);

  @override
  _GoogleMapScreenState createState() => _GoogleMapScreenState();
}

class _GoogleMapScreenState extends State<GoogleMapScreen> {
  late GoogleMapController mapController;
  Set<Marker> markers = {};

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void onMapcreated(GoogleMapController controller) {
    setState(() {
      markers.add(const Marker(
        markerId: MarkerId('1'),
        position: LatLng(13.007488, 77.598656),
        infoWindow: InfoWindow(
          title: 'Marker Title Second ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('2'),
        position: LatLng(12.999595, 77.585856),
        infoWindow: InfoWindow(
          title: 'Marker Title Third ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('3'),
        position: LatLng(13.001916, 77.588849),
        infoWindow: InfoWindow(
          title: 'Marker Title Fourth ',
          snippet: 'My Custom Subtitle',
        ),
      ));
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: GoogleMap(
          initialCameraPosition: const CameraPosition(
            target: LatLng(36.736847, 4.045026),
            zoom: 15,
          ),
          mapToolbarEnabled: true,
          buildingsEnabled: false,
          myLocationButtonEnabled: true,
          mapType: MapType.normal,
          markers: markers,
          onMapCreated: onMapcreated,
        ),
      ),
    );
  }
}

Output

I used the Empty API key for Google API.

And also I need to hide the plus, minus symbol & copyrights from the map

Body:
You need to have Google Map API Key Otherwise you'll see an empty white screen.

I tried your code only machine with google api key and it's working fine.
here is the code I've used(try to copy paste and check)

2.for hiding zoom button use zoomControlsEnabled: true,

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapScreen extends StatefulWidget {
  const GoogleMapScreen({Key? key}) : super(key: key);

  @override
  _GoogleMapScreenState createState() => _GoogleMapScreenState();
}

class _GoogleMapScreenState extends State<GoogleMapScreen> {
  late GoogleMapController mapController;
  Set<Marker> markers = {};

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void onMapcreated(GoogleMapController controller) {
    setState(() {
      markers.add(const Marker(
        markerId: MarkerId('1'),
        position: LatLng(13.007488, 77.598656),
        infoWindow: InfoWindow(
          title: 'Marker Title Second ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('2'),
        position: LatLng(13.007481, 77.598651),
        infoWindow: InfoWindow(
          title: 'Marker Title Third ',
          snippet: 'My Custom Subtitle',
        ),
      ));
      markers.add(const Marker(
        markerId: MarkerId('3'),
        position: LatLng(13.001916, 77.588849),
        infoWindow: InfoWindow(
          title: 'Marker Title Fourth ',
          snippet: 'My Custom Subtitle',
        ),
      ));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      extendBodyBehindAppBar: true,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: GoogleMap(
          initialCameraPosition: const CameraPosition(
            target: LatLng(13.007481, 77.598656),
            zoom: 10,
          ),
          mapToolbarEnabled: true,
          buildingsEnabled: false,
          myLocationButtonEnabled: true,
          mapType: MapType.normal,
          markers: markers,
          onMapCreated: onMapcreated,
          zoomControlsEnabled: true,
        ),
      ),
    );
  }
}

Note:
I guess the problem was that your target LatLng was referring to the
different location and another reason could be that you didn’t
provided API key.

your earlier targer was 36.736847, 4.045026 to which i changed to 13.007488, 77.598656 nearest to your marker, including your zoom value from 15 to 10


问:
Cursor input errors when multithreading with python curses librairy
I'm trying to use curses for a class project where we need to use python

The premise is a server/client chat. I was trying to implement it such that the incoming messages from the server would be displayed above the message prompt. I was able to circumvent the python input() function pausing the program with a second thread displaying the messages I decided to use curses to print things at different parts of the screen.

when I tried multi threading with curses I it had a lot of issues with the input cursor. It used displayed the characters that were being input to the program right next to the incoming chat text despite the cursor visually moving back on the screen to the input area

I've isolated the code that's supposed to make this happen:

```<code>import threading
from time import sleep
import curses

screen = curses.initscr()

screen.clear()
screen.refresh()
num_rows, num_cols = screen.getmaxyx()

#prints what would be chat to the top of the screen
def thread_delay(thread_name, delay):
    i = 0
    while i < 10:
        #is supposed to save the cursor's location before moving it
        global x_location, y_location
        x_location, y_location = curses.getsyx()
        screen.addstr(0+i, 0, "stuff")
        screen.refresh()

        #is supposed to restore the cursor to the input location
        curses.setsyx(x_location, y_location)
        curses.doupdate()
        sleep(1)
        i+=1
#gets and displays input to the bottom of the screen
def my_raw_input(stdscr, r, c, prompt_string):
    curses.echo()

    stdscr.addstr(r, c, prompt_string)
    stdscr.refresh()
    global input
    input = stdscr.getstr(r + 1, c, 20)
    return  #       ^^^^  reading input at next line

#threads
t1 = threading.Thread(target = thread_delay, args = ('t1', 1,))
t2 = threading.Thread(target = my_raw_input, args = (screen, num_rows - 4, 0, "type what you want"))
t1.start()
t2.start()
t1.join()
t2.join()
curses.napms(3000)
curses.endwin()

#for debugging
print(input.decode('utf-8'))
</code>```

Picture of what is happening vs what's supposed to happen:

答:
I guess your class is over, so it might not be useful anymore...

There are several problems....

first problem is that you are not accepting curses text input, and instead using standard input. The curses module, works by moving the cursor around and adding a character, so wherever your last addstr or addch command ends is where the cursor is positioned, and will next add text. So you could possibly move the cursor back to where you want the input to go, after writing to the screen or you could use curses to capture keyboard input.

Secondly using curses in two processes at the same time is probably not a good idea, since it bypasses the GIL. Instead, you could split your code threads into a server and a curses TUI, and share a global send queue and a receive queue from the multiprocessing.Manager to transfer messages.

Then your server thread can send messages from the send_queue with a .get() and receive messages and putting them in the receive_queue with a .put(). Conversely your curses thread can display messages from the recv_queue with a .get() and put a string composed from curses.getch() or curses.getkey() into the send_queue with a .put()

also consider using the curses.wrapper to simplify entering and exiting your curses features. I think you probably didn't use this, because you tried to use curses over multiple processes in which case a wrapper might not work so well.

I'm sure there are other and probably better ways to do it, but this is just one of many. But I hope this helps someone, or encourages someone more experienced to contribute a better answer.

Body:
I'm trying to use curses for a class project where we need to use python

The premise is a server/client chat. I was trying to implement it such that the incoming messages from the server would be displayed above the message prompt. I was able to circumvent the python input() function pausing the program with a second thread displaying the messages I decided to use curses to print things at different parts of the screen.

when I tried multi threading with curses I it had a lot of issues with the input cursor. It used displayed the characters that were being input to the program right next to the incoming chat text despite the cursor visually moving back on the screen to the input area

I've isolated the code that's supposed to make this happen:

import threading
from time import sleep
import curses

screen = curses.initscr()

screen.clear()
screen.refresh()
num_rows, num_cols = screen.getmaxyx()

#prints what would be chat to the top of the screen
def thread_delay(thread_name, delay):
    i = 0
    while i < 10:
        #is supposed to save the cursor's location before moving it
        global x_location, y_location
        x_location, y_location = curses.getsyx()
        screen.addstr(0+i, 0, "stuff")
        screen.refresh()

        #is supposed to restore the cursor to the input location
        curses.setsyx(x_location, y_location)
        curses.doupdate()
        sleep(1)
        i+=1
#gets and displays input to the bottom of the screen
def my_raw_input(stdscr, r, c, prompt_string):
    curses.echo()

    stdscr.addstr(r, c, prompt_string)
    stdscr.refresh()
    global input
    input = stdscr.getstr(r + 1, c, 20)
    return  #       ^^^^  reading input at next line

#threads
t1 = threading.Thread(target = thread_delay, args = ('t1', 1,))
t2 = threading.Thread(target = my_raw_input, args = (screen, num_rows - 4, 0, "type what you want"))
t1.start()
t2.start()
t1.join()
t2.join()
curses.napms(3000)
curses.endwin()

#for debugging
print(input.decode('utf-8'))

Picture of what is happening vs what's supposed to happen:


问:
What is default behavior of Kubernetes when pod crashes?
In Kubernetes deployment with 4 static pods and no autoscaling, what happens by default if one pod crashes? Will it be re-created automatically with the same ID/different ID or will the application continue running on 3 pods?</p>

答:
When a pod crashes, it will automatically be restarted. You will see this by the incrementing value of the pod's "Restarts" value when you do kubectl get pods

From the documentation: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#pod-template

Only a .spec.template.spec.restartPolicy equal to Always is allowed, which is the default if not specified.

In other words, a deployment will ALWAYS restart your pod, regardless, and you cannot change that behaviour.

A restart will not change the name of the pod (or ID has you have called it)

The only time the pod name will change is if the pod gets deleted. This can happen during autoscaling processes or if the pod gets evicted from a node.

You've specified no autoscaling in your deployment, but if you have specified a value of 4 replicas, as I suspect you have, then the eviction will cause that one pod to change names, as it gets recreated by another node, in order to meet your request for 4 replica.

By "changing names" I just mean the hash at the end of the pod name will change. So your pod named my-test-g4gsv may be renamed to my-test-4dsv4 after it goes to a new node.

There is a backoff policy for restarts. So if Kubernetes detects a pod has been restarted repeatedly, it will start delaying its restart attempts. You will notice this as a CrashLoopBackoff value under the pod status (instead of Running). While in this state, the pod is not started, so during this time, your deployment is essentially running with reduced replicas until Kubernetes starts it.


问:
How can I insert a '-' in my string?
I have a string that can look like this: 12345, this 123456 or this: 1234567.

I'd like to make each string look like this: 123-45, this: 1234-56 or this: 12345-67.

How can I do this in C#?

答:
```<code>string s = "teststring";
string newString = s.Insert(s.Length-2,"-");
</code>```

This is assuming you want the '-' to appear two from the end :-)

This could be handy (untested)

```<code>    /// <summary>
    /// Takes a string and and inserts a spacer character at
    /// a specifed distance from the end
    /// </summary>
    /// <param name="input">string to modify</param>
    /// <param name="spacer">string to insert</param>
    /// <param name="positionFromEnd">insertion point</param>
    /// <returns></returns>
    protected string AddSpacer(string input, string spacer, int positionFromEnd)
    {
        string outputString = string.Empty;

        if (input.Length >= positionFromEnd)
        {
            outputString = input.Insert(input.Length - positionFromEnd, spacer);
        }
        else
        {
            throw new Exception("The position you tried to insert the spacer into doesn't exist");
        }

        return outputString;
    }
</code>```

Title: How can I insert a '-' in my string?

Body:
string s = "teststring";
string newString = s.Insert(s.Length-2,"-");

This is assuming you want the '-' to appear two from the end :-)

This could be handy (untested)

    /// <summary>
    /// Takes a string and and inserts a spacer character at
    /// a specifed distance from the end
    /// </summary>
    /// <param name="input">string to modify</param>
    /// <param name="spacer">string to insert</param>
    /// <param name="positionFromEnd">insertion point</param>
    /// <returns></returns>
    protected string AddSpacer(string input, string spacer, int positionFromEnd)
    {
        string outputString = string.Empty;

        if (input.Length >= positionFromEnd)
        {
            outputString = input.Insert(input.Length - positionFromEnd, spacer);
        }
        else
        {
            throw new Exception("The position you tried to insert the spacer into doesn't exist");
        }

        return outputString;
    }