2021年11月24日 星期三

Cursor Movement (轉貼)

 

Cursor Movement

ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:

- Position the Cursor:
  \033[<L>;<C>H
     Or
  \033[<L>;<C>f
  puts the cursor at line L and column C.
- Move the cursor up N lines:
  \033[<N>A
- Move the cursor down N lines:
  \033[<N>B
- Move the cursor forward N columns:
  \033[<N>C
- Move the cursor backward N columns:
  \033[<N>D

- Clear the screen, move to (0,0):
  \033[2J
- Erase to end of line:
  \033[K

- Save cursor position:
  \033[s
- Restore cursor position:
  \033[u

2021年11月7日 星期日

Can't pickle local object 'CDLL.__init__.._FuncPtr'解法

 以下Error Message:

  File "app.py", line 624, in instrument_ready
    pickle.dump(visa_values_instruments_to_dump, f)
AttributeError: Can't pickle local object 'CDLL.__init__.<locals>._FuncPtr'

可能原因在於DLL相關的東西,無法pickle.

解法:將__init__()中可能包到的DLL,在其它函式再呼叫。

class VisaInstrument(Instrument):

    dll_32 = 'C:/Windows/System32/visa32.dll'

    def __init__():

        ...

        #將self.rm改成注解

        #self.rm = visa.ResourceManager(self.dll_32)

        ...

...

 def open(self):

        try:

            #self.dev = self.rm.open_resource(self.visa_addr)

            import pyvisa as visa # Simon added 20211108

            self.dev = visa.ResourceManager(self.dll_32).open_resource(self.visa_addr)

            ...

        except Exception as ex:

            return False

        else:

            return True

2021年11月4日 星期四

Remote branches with TortoiseGit (轉貼)

 

Git makes branching easy. Coming from other version control systems the work flow isn't always as easy to understand though. Here's what I've found works well when using Tortoise Git.

As a user of TortoiseGit I’ve always been a bit confused when it comes to dealing with remote branches. Git makes it really easy and fast to work with branches compared to many version control systems that aren’t distributed, but coming from the world of TFS or SubVersion where a branch is basically a physical directory that one can check in and check out in Git it’s pretty much just a pointer. This means that a branch is unique to each repository and the workflow when wanting to push a local branch to a remote repository, or the opposite, is a bit different.

The documentation for handling branches using the console is great, but when I’ve been using TortoiseGit I’ve often felt confused and insecure when dealing with remote branches. I therefor decided to do some research and experimentation and document a workflow that seems to work.

Creating a local branch

Given that we’ve created a local repository and added a remote to it, in my case a GitHub repository, we can create a local branch by right clicking in a directory in the repository and pick the Create Branch menu item.

TortoiseGit Create Branch right click menu option

We then get the Create Branch dialog where we enter a name for the branch and hit OK.

TortoiseGit Create Branch dialog

Unless we didn’t check the “Switch to new branch” checkbox in the Create Branch dialog our working directory is still the master branch. To switch to the newly created branch we right click and pick the Switch/Checkout menu item.

TortoiseGit Switch/Checkout right click menu option

In the following dialog we choose our newly created local branch and hit OK.

TortoiseGit Checkout/Switch dialog

Our working directory is now the newly created branch (“branch1” in my case). We can now make some changes and commit them to the local branch. This is reflected in the Commit menu item in TortoiseGit’s right click menu.

TortoiseGit Commit right click menu option

Pushing the local branch to a new remote branch (on GitHub)

When we want to share our local branch with others, or store it in a remote repository to back it up or be able to retrieve it from another computer we need to push. To me this is slightly confusing as pushing it doesn’t mean pushing that actual branch to the remote repository but rather creating a new branch in the remote repository and pushing the changes. To do this we use the Push right click menu option just like we would have if we were working in the master branch.

TortoiseGit Push right click menu option

In the following Push dialog we simply hit OK.

TortoiseGit Push dialog

This is one of the parts that have confused me the most. I’ve always wondered if this didn’t mean that the changes in the local branch wasn’t going to be pushed to the master branch in the remote repository. But looking at the Git Command Progress dialog after hitting OK we see that TortoiseGit pushes the local branch to a branch with the same name in the remote repository which will then be created as it doesn’t yet exist.

TortoiseGit Git Command Progress dialog

After pushing the branch to GitHub (if that’s where our remote repository is) we can see it and switch to it using the Branches button to the right of the page.

GitHub Switch Branches/Tags dialog

After having made some more changes that we’ve committed to our local branch we can push them to the corresponding remote branch using the same workflow.

TortoiseGit Push dialog

As we can see in the Command Progress dialog the changes in our local branch is pushed to the corresponding remote branch.

TortoiseGit Git Command Progress dialog

Fetching the remote branch

When someone else wants to fetch our new branch from the remote repository, our after having switched to another computer or local repository ourselves, we need to fetch the new branch from the remote repository. One might think that this involves first creating a new local branch and then pulling from the remote branch but according to my research that’s not a good idea. Instead, what we want to do is create a new local branch based on the remote branch. We do this by first choosing the Create Branch right click menu option.

TortoiseGit Create Branch right click menu option

In the Create Branch dialog we can name our new branch whatever we want, but to avoid confusion we most likely want to give it the same name as the remote branch. The trick then is to check the Base on/Branch radio button and choose the remote branch.

TortoiseGit Create Branch dialog

After hitting OK we get a confirmation that the new local branch has been created and that it tracks the remote branch. Just like before we also need to either check the “Switch to new branch” checkbox or manually checkout the new branch in order to start working in it.

TortoiseGit Branch set up dialog

After having committed changes to our local branch we can push changes to the remote branch using the Push right click menu option. We need however to make sure that the correct branch is selected in the Remote drop down in the Push dialog.

TortoiseGit Push dialog

Merging

Once we want to merge changes in the branch into the master branch we checkout the master branch using the Checkout/Switch right click menu option.

TortoiseGit Checkout/Switch dialog

We then use the Merge right click menu option…

TortoiseGit Merge right click menu option

…to bring up the Merge dialog where we select to merge from our local branch.

TortoiseGit Merge dialog

With the merge done we can push the changes (the merge) from our local master to the remote master branch.

TortoiseGit Push dialog

The remote repository will then figure out what has happened and if we look at the Network tab in GitHub it will appear as the branch we’ve been working with never existed (more or less).

Deleting the local branch

If we’re done with our branch after having merged it into master, or if we want to discard the branch for some other reason, we can remove the local branch by first opening up the Checkout/Switch dialog to get at the Browse refs dialog.

TortoiseGit Checkout/Switch dialog

In the Browse refs dialog we can right click on the local branch and choose to delete it.

TortoiseGit Browse refs dialog - Delete Local Branch

Deleting the remote branch

To delete a remote branch we can do the same thing, but instead of right clicking on our local branch we expand the remotes tree in the left part of the dialog and then locate the remote branch.

TortoiseGit Browse refs dialog - Delete Remote Branch

Disclaimer

I’m no expert at Git (although I hope to be some day) so if you see something wrong in this post don’t hesitate to let me know! This workflow does seem to work well for me though.

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

2021年10月26日 星期二

在macos的python2安裝pip模組 (轉貼)

 To install pip for Python 2.7 install it from https://bootstrap.pypa.io/pip/2.7/ :

- curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py
- python get-pip.py
- (python -m pip install --upgrade "pip < 21.0")
The last command is to upgrade to the latest supported version. For Python 2.7 the latest supported is currently pip 20.3.4.

2021年10月16日 星期六

Soft Link vs Hard Link (轉貼)

 軟連結與硬軟結的資料對應關係

硬連結直接透過分割區上的配置表來對應資料,只能在本機硬碟使用,無法跨分割。軟連結要再透過硬連結來存取硬碟上的資料,可跨網路。

硬連結?軟連結?檔案分身不乏術

2021年10月7日 星期四

How to Set Root View Controller Programmatically in Swift 5 & Xcode 12

 Ref: https://www.youtube.com/watch?v=u-cK4HdEO30


In Xcode 12:

1. Click <Project Name>

2. In TARGETS -> General -> Deployment Info -> Main Interface

3. Select what you want (story file)

2021年10月1日 星期五

String.Index work in Swift (轉貼)

 

How does String.Index work in Swift

Strings and Indexing it has been a pain to understand things. 

Specifically I was trying the following:

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5) // error

where the second line was giving me the following error

'advancedBy' is unavailable: To advance an index by n steps call 'index(_:offsetBy:)' on the CharacterView instance that produced the index.

I see that String has the following methods.

str.index(after: String.Index)
str.index(before: String.Index)
str.index(String.Index, offsetBy: String.IndexDistance)
str.index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)

These were really confusing me at first so I started playing around with them until I understood them. I am adding an answer below to show how they are used.

324

enter image description here

All of the following examples use

var str = "Hello, playground"

startIndex and endIndex

  • startIndex is the index of the first character
  • endIndex is the index after the last character.

Example

// character
str[str.startIndex] // H
str[str.endIndex]   // error: after last character

// range
let range = str.startIndex..<str.endIndex
str[range]  // "Hello, playground"

With Swift 4's one-sided ranges, the range can be simplified to one of the following forms.

let range = str.startIndex...
let range = ..<str.endIndex

I will use the full form in the follow examples for the sake of clarity, but for the sake of readability, you will probably want to use the one-sided ranges in your code.

after

As in: index(after: String.Index)

  • after refers to the index of the character directly after the given index.

Examples

// character
let index = str.index(after: str.startIndex)
str[index]  // "e"

// range
let range = str.index(after: str.startIndex)..<str.endIndex
str[range]  // "ello, playground"

before

As in: index(before: String.Index)

  • before refers to the index of the character directly before the given index.

Examples

// character
let index = str.index(before: str.endIndex)
str[index]  // d

// range
let range = str.startIndex..<str.index(before: str.endIndex)
str[range]  // Hello, playgroun

offsetBy

As in: index(String.Index, offsetBy: String.IndexDistance)

  • The offsetBy value can be positive or negative and starts from the given index. Although it is of the type String.IndexDistance, you can give it an Int.

Examples

// character
let index = str.index(str.startIndex, offsetBy: 7)
str[index]  // p

// range
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
str[range]  // play

limitedBy

As in: index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)

  • The limitedBy is useful for making sure that the offset does not cause the index to go out of bounds. It is a bounding index. Since it is possible for the offset to exceed the limit, this method returns an Optional. It returns nil if the index is out of bounds.

Example

// character
if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
    str[index]  // p
}

If the offset had been 77 instead of 7, then the if statement would have been skipped.

Why is String.Index needed?

It would be much easier to use an Int index for Strings. The reason that you have to create a new String.Index for every String is that Characters in Swift are not all the same length under the hood. A single Swift Character might be composed of one, two, or even more Unicode code points. Thus each unique String must calculate the indexes of its Characters.

It is possible to hide this complexity behind an Int index extension, but I am reluctant to do so. It is good to be reminded of what is actually happening.

  • 25
    Why would startIndex be anything else than 0?  Jul 3 '17 at 11:44
  • 23
    @RoboRobok: Because Swift works with Unicode characters, which are made of "grapheme clusters", Swift doesn't use integers to represent index locations. Let's say your first character is an é. It is actually made of the e plus a \u{301} Unicode representation. If you used an index of zero, you would get either the e or the accent ("grave") character, not the entire cluster that makes up the  é. Using the startIndex ensures you'll get the entire grapheme cluster for any character. 
    – leanne
     Aug 18 '17 at 16:16 
  • 3
    In Swift 4.0 each Unicode characters are counted by 1. Eg: "👩‍💻".count // Now: 1, Before: 2 
    – selva
    Sep 29 '17 at 6:50 
  • 3
    How does one construct a String.Index from an integer, other than building a dummy string and using the .index method on it? I don't know if I'm missing something, but the docs don't say anything. 
    – sudo
     Oct 10 '17 at 20:43 
  • 3
    @sudo, you have to be a little careful when constructing a String.Index with an integer because each Swift Character does not necessarily equal the same thing you mean with an integer. That said, you can pass an integer into the offsetBy parameter to create a String.Index. If you don't have a String, though, then you can't construct a String.Index (because Swift can only calculate the index if it knows what the previous characters in the string are). If you change the string then you must recalculate the index. You can't use the same String.Index on two different strings. 
    – Suragch
     Oct 11 '17 at 2:15