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