特斯拉將在蘇州成立生產基地?

作為全球最具潛力的電動車市場之一,特斯拉(Tesla)也持續傳出有在中國設置本土化生產基地的消息。日前中國流出一份文件,內容是關於蘇州召開會議討論特斯拉汽車項目入主蘇州的相關事宜,似乎代表特斯拉已選定了地點。

根據中國網路媒體《第一電動網》所獲得的資訊,蘇州相關政府部門於3月13日召開專題會議,研究協調特斯拉的汽車生產工廠成立相關事宜。通知內容如下:

經研究,市委副書記、常務副市長周偉強定於3月13日(星期天)上午9:00,在市政府1號會議室召開專題會議,研究協調特斯拉汽車項目落戶蘇州的相關事宜。會議主要有三項議程:一是請商務局通報該項目整體情況;二是請各有關地區匯報爭取該項目落地的相關意見和措施(如土地供應等方面,書面材料請帶5份至會);三是市各有關部門就推進該項目提出有關建議(項目情況見附件)。

請各地政府(管委會)、各有關部門主要領導或分管領導準時參會(可攜帶具體業務負責同志),特此通知。

據了解,特斯拉高層於3月17、18日拜訪蘇州進行實地考察,但《第一電動網》對此事進行深入訪談,包括蘇州商務局等相關人士均沒有正面回應。特斯拉近來一直被傳言將在中國尋找合資夥伴並設立工廠,也有許多中國公司主動表達合作意願,不過特斯拉對於在中國設廠一事一直沒有明確的回答。

台灣特斯拉汽車公司日前正式登記成案,特斯拉在中國的動向也值得關切。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

整數的表示與編碼

補一下CSAPP的筆記

計算機中整數的表示與編碼

計算機中的整數主要包括兩種:有符號數與無符號數。

無符號數的編碼

其中有符號數的表示方法與傳統二進制一致。
假設有一個整數數據類型有w位。我們可以將位向量寫成

在這個編碼中,每個xi都取值為0或1。我們用一個函數來表示B2Uw來表示:

無符號數的編碼方式實際上與我們所知道的二進制編碼方式是一致的。唯一要注意的是無符號數的編碼具有唯一性,也就是說一個数字只能有一個無符號數編碼。這是因為B2Uw是一個雙射。

有符號數的編碼

有符號數的編碼主要有三種方式:原碼、補碼與反碼。我曾經寫過一篇博客來進行探究,這裏不贅述。

需要說明的是:補碼也具有唯一性,原碼與反碼不具備這種性質,因為0在原碼與反碼中有兩種解釋。

有符號數與無符號數之間的轉換

有符號數轉無符號數

C語言中提供了在不同數據類型中做強制類型轉換的方法,對於無符號整數與有符號整數之間的轉換方式,大多數系統上默認的是底層的位不變,由此我們能推出有符號數與無符號數之間的轉換。
關於這些的轉換的的過程和原理,在此不贅述。這裏直接給出公式:
一個數的編碼方式從無符號編碼(補碼)轉換為有符號編碼后的數值公式為:

如果有符號數的真值小於0那麼,把真值加上2w即為其無符號真值,如果真值大於0,那麼不變。
我們用一段C語言代碼舉例:

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main(void)
{
    int i = -1;
    unsigned int j = (unsigned int)i;
    printf("%u\n", j);
    printf("%u\n", UINT_MAX);
    system("pause");
}

VS2017下的運行結果:

數據類型int的大小為8字節,32位,把-1轉換成無符號數需要加上232,結果為232-1,正好為無符號數編碼的最大值,所以與UINT_MAX的值一致。

無符號數轉有符號數

直接給出公式:

C語言代碼測試實例:

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main(void)
{
    unsigned int i = UINT_MAX;
    int j=(int)i;
    printf("%d", j);
    system("pause");
}

VS2017下的運行結果:

需要說明的是,在VS2017的環境下,上面兩個程序經過測試即使不使用強制類型轉換也可以得到正確的結果,其一是C語言中如果發現左右兩邊數據類型不一致會自動把數據往左邊的類型轉換,其二是,printf中的格式說明符也會自動執行類型轉換,這裏使用強制類型轉換隻是為了讓轉換看起來更加清晰。

無符號整數與有符號整數互相轉換可能遇到的問題

由於C語言對同時包含有符號和無符號數表達式的這種處理方式,出現了一些奇特的行為。當執行一個運算時如果它的一個運算數是有符號的而另一個是無符號的,那麼C語言會隱式地把有符號參數強制類型轉換為無符號,並假設這兩個數都是非負的
對於 這樣的關係運算符來說,它會導致非直觀的結果。我們同樣用一個C語言程序來作為測試:

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    printf("%d", -1 < 0U);
    printf("%d",(unsigned)-1 > -2);
}

VS2017運行結果:

第一個表達式中,由於0是無符號數,所以-1默認變成無符號數,即為232-1,這個數必然比0要大。所以第一個表達式為假。
第二個表達式中,通過把-1強制轉換成無符號數,-1變為232-1,-2變為232-2,所以第二個表達式為真。

擴展一個数字的位表示

有時我們會把一個佔用空間較小的數據類型轉換為佔用空間較大的數據類型(如果把佔用空間較大的數據類型轉換為佔用空間較小的數據類型,可能會丟失數據,我們一般不推薦這麼做)。

無符號數的零擴展

定義寬度為w位的位向量:

和寬度為w’的位向量:

其中w’>w。則:

要將一個無符號數轉換為一個更大的無符號數數據類型,我們只要簡單的在前面加上足夠的0即可,這種運算被稱為零擴展。

有符號數的符號拓展

定義寬度為w位的位向量:

和寬度為w’的位向量:

其中w’>w。則:

要將補碼数字轉換為一個更大的數據類型,可以執行一個符號擴展(sign-extension),在前面添加最高有效位的值。
具體證明略。

值得注意的點:在C語言中,把類型不同、大小不同的兩個數據類型相互轉換,先改變數據類型的大小,然後在執行類型轉換。
比如說:在C語言中,把一個short類型的變量轉換為unsigned類型的變量,我們要先把short類型的變量擴展到8個字節,然後再執行有符號數到無符號數的轉換。

截斷数字

一些特殊情況下,儘管這樣做會帶來風險,但我們仍然有時候會需要把一個高位的數據類轉換為低位的數據類型,這時候我們就需要截斷這個数字。

無符號數的截斷

定義寬度為w位的位向量:

而它截斷為k位的結果為:

令x=B2U_w(\vec x),x’=B2U_(\vec x’),則x’=x mod 2^k。
截斷為k為實際上就是對原數的真值用2^k取模。具體證明過程略。

有符號數的截斷

要理解有符號數的截斷,我們首先要明白,無論是有符號數還是無符號數真正區別他們的不是他們的真值,而是他們的編碼方式,實際上無論是有符號數,還是無符號數,在內存中都表示為串二進制數,有了編碼對他們真值的解釋,他們才能表示不同的數據。
我們都知道,截斷實際上就是截去前面冗餘的位,只留下我們需要的位,既然無符號數和有符號數在內存中表示的方法實際上都是一串二進制數,我們為什麼不可以把一個有符號數的位模式,看做是無符號數的編碼,用無符號數的方式將其截斷後得到的真值,再用把無符號數轉換為有符號數,最終得到將有符號數階段的真值。
總而言之,有符號數編碼的截斷結果是:

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

研究:極地冰蓋以1990年代六倍速融化 每年將有4億人受洪災影響

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

能源局將在4-6月開展電動汽車充電基礎設施安全專項檢查

4月6日從能源局獲悉,國家能源局綜合司發佈《關於開展電動汽車充電基礎安全專項檢查的通知》,旨在加強電動汽車充電基礎設施安全管理,促進能源互聯網建設和新能源汽車產業發展。

通知指出,加強電動汽車充電基礎設施安全管理,促進能源互聯網建設和新能源汽車產業發展,定於2016年4月-6月在全國範圍內組織開展電動汽車充電基礎設施安全專項檢查。

通知明確檢查物件和內容,重點對電動汽車充電基礎設施建設運營企業以及相關充換電設施進行檢查,包括電動汽車充電基礎設施安全管理、設備設施及監控系統安全運行、建設標準執行等情況。

通知要求,全面加強電動汽車充電基礎設施安全運營管理,建立設備設施定期檢查和運行維護工作制度,確保充電設備、配電設備、線纜及保護裝置、充電監控系統及運行管理平臺的工作狀態正常和可靠運行。落實充電設備、配電等電氣設備及監控系統故障資訊檢測手段,建立充電過程的告警監測、過充保護、故障處理等防控措施及應急聯動機制。依照相關標準對有關消防設施進行檢查,保證設備處於可用狀態。加強設備設施安全管理和運行維護,滿足充換電設施運行要求。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

Asciinema文章勘誤及Web端使用介紹

欠下的債遲早是要還的,查文檔,重驗證,出結果,不誤導

文章勘誤

在上一篇文章中有兩個地方表述有錯誤或瑕疵,這裏更正一下

第一個地方為錄製時的參數--stdin,參數的意思是啟用標準輸入錄製,原文中說看不到效果,可能官方還未支持,實際上官方已經支持了,且查看錄製文件內容時可以看到區別,以下兩個對比的例子來說明

例一:執行下方的命令進行錄製,錄製開始之後執行ssh命令輸入密碼連接另一台主機

asciinema rec ops-coffee.cast

執行asciinema cat命令查看執行命令

# asciinema cat ops-coffee.cast 
root@onlinegame:~# ssh root@192.168.106.192 ls ops-coffee.cn
root@192.168.106.192's password: 
ops-coffee.cn
root@onlinegame:~# exit
exit

打印錄製的文件內容如下:

# cat ops-coffee.cast 
{"version": 2, "width": 237, "height": 55, "timestamp": 1574060513, "env": {"SHELL": "/bin/bash", "TERM": "linux"}}
[0.012221, "o", "root@onlinegame:~# "]
[0.607184, "o", "exit"]
[1.07092, "o", "\b\b\b\bssh root@192.168.106.192 ls ops-coffee.cn"]
[1.703405, "o", "\r\n"]
[1.762974, "o", "root@192.168.106.192's password: "]
[4.550759, "o", "\r\n"]
[4.558138, "o", "ops-coffee.cn\r\n"]
[4.559187, "o", "root@onlinegame:~# "]
[5.182817, "o", "e"]
[5.582643, "o", "x"]
[5.838648, "o", "i"]
[6.03067, "o", "t"]
[6.759346, "o", "\r\nexit\r\n"]

例二:執行同樣的命令,加上--stdin參數

asciinema rec --stdin ops-coffee.1.cast

執行asciinema cat命令查看執行命令

# asciinema cat ops-coffee.1.cast 
root@onlinegame:~# ssh root@192.168.106.192 ls ops-coffee.cn
root@192.168.106.192's password: 
ops-coffee.cn
root@onlinegame:~# exit
exit

這次再看錄製文件的內容:

# cat ops-coffee.1.cast
{"version": 2, "width": 237, "height": 55, "timestamp": 1574060808, "env": {"SHELL": "/bin/bash", "TERM": "linux"}}
[0.01012, "o", "root@onlinegame:~# "]
[1.654752, "i", "\u001b[A"]
[1.654971, "o", "exit"]
[2.014568, "i", "\u001b[A"]
[2.014727, "o", "\b\b\b\bssh root@192.168.106.192 ls ops-coffee.cn"]
[3.7185, "i", "\r"]
[3.719167, "o", "\r\n"]
[3.781231, "o", "root@192.168.106.192's password: "]
[5.198467, "i", "s"]
[5.542343, "i", "m"]
[5.774451, "i", "i"]
[5.85435, "i", "l"]
[5.990628, "i", "e"]
[6.342587, "i", "\r"]
[6.342817, "o", "\r\n"]
[6.351245, "o", "ops-coffee.cn\r\n"]
[6.351475, "o", "root@onlinegame:~# "]
[7.182384, "i", "e"]
[7.182585, "o", "e"]
[7.461976, "i", "x"]
[7.462183, "o", "x"]
[7.543019, "i", "i"]
[7.543306, "o", "i"]
[7.686868, "i", "t"]
[7.68703, "o", "t"]
[7.87045, "i", "\r"]
[7.871348, "o", "\r\nexit\r\n"]

會發現在實際執行命令完全一致的情況下,錄像文件與上一個沒有加--stdin時的不一樣,其中就多了輸入密碼的記錄smile

且在asciinema文件IO流信息的第二個字段不僅有了o,還有i的出現,上一篇文章講到o是一個固定字符串不知道作用,經過深入查詢確認,IO信息流的第二個字段就是固定string字符串,且只會是io之間的一種,分別表示stdin標準輸入或stdout標準輸出

--stdin的效果無論是通過asciinema play命令播放或是asciinema cat命令查看都是無法察覺的,在實現WebSSH錄像回放時又對錄像文件進行了深入研究,最終發現問題,這裏查漏補缺,予以更正,對於之前的錯誤,深表歉意

Web端使用

asciinema錄製文件在web端播放是通過asciinema-player組件來實現的,使用也是非常的簡單

分別引入css和js文件,添加一個asciinema-player的標籤即可播放標籤內文件的錄像

<html>
<head>
  ...
  <link rel="stylesheet" type="text/css" href="/asciinema-player.css" />
  ...
</head>
<body>
  ...
  <asciinema-player src="/ops-coffee.cast"></asciinema-player>
  ...
  <script src="/asciinema-player.js"></script>
</body>
</html>

asciinema-player標籤內可以添加如下一些屬性:

cols: 播放終端的列數,默認為80,如果cast文件的header頭有設置width,這裏無需設置

rows: 播放終端的行數,默認為24,如果cast文件的header頭有設置height,這裏無需設置

autoplay: 是否自動開始播放,默認不會自動播放

preload: 預加載,如果你想為錄像配音,這裏可以預加載聲音

loop: 是否循環播放,默認不循環

start-at: 從哪個地方開始播放,可以是123這樣的秒數或者是1:06這樣的時間點

speed: 播放的速度,類似於play命令播放時的-s參數

idle-time-limit: 最大空閑秒數,類似於play命令播放時的-i參數

poster: 播放之前的預覽,可以是npt:1:06這樣給定時間點的畫面,也可以是data:text/plain,ops-coffee.cn這樣給定的文字,其中文字支持ANSI編碼,例如可以給文字加上顏色data:text/plain,\x1b[1;32mops-coffee.cn\x1b[1;0m

font-size: 文字大小,可以是smallmediumbig或者直接是14px這樣的css樣式大小

theme: 終端顏色主題,默認是asciinema,也提供有tangosolarized-darksolarized-light或者monokai可選擇,當然你也可以自定義主題

還有幾個參數titleauthorauthor-urlauthor-img-url分別表示了錄像的標題、作者、作者的主頁、作者的頭像,這些配置會在全屏觀看錄像時显示在標題欄中,像下邊這樣

最後使用以下參數設置asciinema-player,看看播放的效果

<asciinema-player id="play" 
    title="WebSSH Record" 
    author="ops-coffee.cn" 
    author-url="https://ops-coffee.cn" 
    author-img-url="/static/img/logo.png" 
    src="/static/record/ops-coffee.cast" 
    speed="3" idle-time-limit="2" 
    poster="data:text/plain,\x1b[1;32m2019-11-18 16:26:18\x1b[1;0m用戶\x1b[1;32madmin\x1b[1;0m連接主機\x1b[1;32m192.168.106.101:22\x1b[1;0m的錄像記錄">
</asciinema-player>

播放效果如下

同時asciinema-player播放時還支持以下快捷鍵的使用

  • space 空格,播放或暫停
  • f 全屏播放,可以看到title等設置
  • / 快進或快退,每次5秒
  • 0,1,6 ... 9 跳轉到錄像的0%,10%,60% … 90%
  • < / > 增加或降低播放速度,play的-s參數

相關文章推薦閱讀:

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

醜聞、禁令、產業競爭  德國交通不得不向低碳轉型

環境資訊中心特約記者 陳文姿報導

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

Appium+python自動化(四十一)-Appium自動化測試框架綜合實踐 – 即將落下帷幕(超詳解)

1.簡介

  今天我們緊接着上一篇繼續分享Appium自動化測試框架綜合實踐 – 代碼實現。到今天為止,大功即將告成;框架所需要的代碼實現都基本完成。

2.data數據封裝

2.1使用背景

在實際項目過程中,我們的數據可能是存儲在一個數據文件中,如txt,excel、csv文件類型。我們可以封裝一些方法來讀取文件中的數據來實現數據驅動。

2.2案例

將測試賬號存儲在account.csv文件,內容如下:

account.csv

hg2018

hg2018

hg2019

zxw2019

666

222

參考代碼

2.3enumerate()簡介

enumerate()是python的內置函數

  • enumerate在字典上是枚舉、列舉的意思
  • 對於一個可迭代的(iterable)/可遍歷的對象(如列表、字符串),enumerate將其組成一個索引序列,利用它可以同時獲得索引和值
  • enumerate多用於在for循環中得到計數。

2.4enumerate()使用

如果對一個列表,既要遍歷索引又要遍曆元素時,首先可以這樣寫:

參考代碼
list = ["", "", "一個", "測試","數據"]

for i in range(len(list)):

    print(i,list[i])

上述方法有些累贅,利用enumerate()會更加直接和優美:

參考代碼
list1 = ["", "", "一個", "測試","數據"]

for index, item in enumerate(list1):

        print(index,item)

3.數據讀取方法封裝

  數據讀取方法也屬於公共方法,這裏我們首先實現一下,然後將其封裝到裡邊即可。

3.1數據讀取方法實現的參考代碼

import csv


     def get_csv_data(csv_file,line):

        with open(csv_file, 'r', encoding='utf-8-sig') as file:

            reader=csv.reader(file)

            for index, row in enumerate(reader,1):

                if index == line:

                    return row

 

    csv_file='../data/account.csv'

    data=get_csv_data(csv_file,3)

    print(data)

3.2封裝

將其封裝在公共方法中,在其他地方用到的時候,直接導入調用即可。

4.utf-8與utf-8-sig兩種編碼格式的區別

UTF-8以字節為編碼單元,它的字節順序在所有系統中都是一樣的,沒有字節序的問題,也因此它實際上並不需要BOM(“ByteOrder Mark”)。但是UTF-8 with BOM即utf-8-sig需要提供BOM。

5.config文件配置

各種配置文件都放在這個目錄下。

5.1日誌文件配置 

主要是一些日誌信息的配置。

log.config

 參考代碼
[loggers]
keys=root,infoLogger

[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler

[logger_infoLogger]
handlers=consoleHandler,fileHandler
qualname=infoLogger
propagate=0

[handlers]
keys=consoleHandler,fileHandler

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form01
args=('../logs/runlog.log', 'a')

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

[formatter_form02]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s

6.測試用例封裝

這裏宏哥舉例給小夥伴們演示:封裝註冊和登錄兩個測試用例。

6.1測試用例執行開始結束操作封裝

測試用例執行開始和結束的封裝,其他模塊用到直接導入,調用即可。

myunit.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-20
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
import unittest
from kyb_testProject.common.desired_caps import appium_desired
import logging
from time import sleep

class StartEnd(unittest.TestCase):
    def setUp(self):
        logging.info('=====setUp====')
        self.driver=appium_desired()

    def tearDown(self):
        logging.info('====tearDown====')
        sleep(5)
        self.driver.close_app()

6.2註冊用例

開始註冊用例代碼邏輯的實現。

test_register.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-20
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
from kyb_testProject.common.myunit import StartEnd
from kyb_testProject.businessView.registerView import RegisterView
import logging,random,unittest

class RegisterTest(StartEnd):
    def test_user_register(self):
        logging.info('======test_user_register======')
        r=RegisterView(self.driver)

        username = 'bjhg2019' + 'fly' + str(random.randint(1000, 9000))
        password = 'bjhg2020' + str(random.randint(1000, 9000))
        email = 'bjhg' + str(random.randint(1000, 9000)) + '@163.com'

        self.assertTrue(r.register_action(username,password,email))

if __name__ == '__main__':
    unittest.main()

6.3登錄用例

開始登錄用例代碼邏輯的實現。

test_login.py

參考代碼
# coding=utf-8
# 1.先設置編碼,utf-8可支持中英文,如上,一般放在第一行

# 2.註釋:包括記錄創建時間,創建人,項目名稱。
'''
Created on 2019-11-13
@author: 北京-宏哥   QQ交流群:707699217
Project:Appium自動化測試框架綜合實踐 - 代碼實現
'''
# 3.導入模塊
from kyb_testProject.common.myunit import StartEnd
from kyb_testProject.businessView.loginView import LoginView
import unittest
import logging

class TestLogin(StartEnd):
    csv_file='../data/account.csv'

    @unittest.skip('test_login_zxw2018')
    def test_login_zxw2018(self):
        logging.info('======test_login_zxw2018=====')
        l=LoginView(self.driver)
        data=l.get_csv_data(self.csv_file,2)

        l.login_action(data[0],data[1])
        self.assertTrue(l.check_loginStatus())

    # @unittest.skip('skip test_login_zxw2017')
    def test_login_zxw2017(self):
        logging.info('======test_login_zxw2017=====')
        l=LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 1)

        l.login_action(data[0], data[1])
        self.assertTrue(l.check_loginStatus())

    @unittest.skip('test_login_error')
    def test_login_error(self):
        logging.info('======test_login_error=====')
        l = LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 3)

        l.login_action(data[0], data[1])
        self.assertTrue(l.check_loginStatus(),msg='login fail!')

if __name__ == '__main__':
    unittest.main()

7.小結

到此,Appium自動化測試框架就差下一篇就全部完成了,聰明的你都懂了嗎???嘿嘿!慢慢地來吧。

下節預告

下一篇,講解執行測試用例,生成測試報告,以及自動化平台,請關注宏哥,敬請期待!!!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

保護黃石國家公園周遭灰熊 美法官出手

摘錄自2018年9月25日中央社報導

美國聯邦法官今天(25日)下令將棲息在黃石國家公園內部及周遭的灰熊,重新列入瀕臨滅絕物種保護法(ESA)保護名單,阻擋40年多來首度開放在這個地區獵捕灰熊的計畫。

美國蒙大拿州密蘇拉(Missoula)聯邦地區法官克里斯坦森(Dana Christensen)與環保人士及美國原住民站在同一陣線,駁回美國魚類暨野生動物管理局(U.S. Fish and Wildlife Service)將灰熊從瀕危物種名單除名的決定。

環保人士主張,根據瀕臨滅絕物種保護法,對這些灰熊與蒙大拿州和下48州(Lower 48)的其他灰熊族群採取差別待遇,是生物學上靠不住且非法行為,法官也同意這類說法。

環保人士說,儘管灰熊數量有所回升,倘若沒有受到聯邦持續保護,牠們的復育情況就會受到影響。此外,氣候變遷導致灰熊食物供給出現變化和人為死亡率高,也對灰熊生存構成威脅。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

騰勢2016年年底前將在中國建650個專屬充電樁

4月25日,騰勢在北京車展發佈全新的騰勢新動生活解決方案,宣佈在2016年年底前在全國建設650個騰勢專屬公共充電樁。針對有長途出行的車主,騰勢還將提供50%的折扣價格租用梅賽德斯-賓士C級轎車的福利。

為解決車主充電難的問題,騰勢將進一步在北上廣深等城市的大型商場、酒店、寫字樓和機場等交通樞紐建設騰勢專屬公共充電樁,預計2016年年底前在全國建設650個騰勢專屬公共充電樁。與此同時,騰勢服務網路在2015年擴大到了9個城市13家銷售服務網點,未來將在重點城市開設更多服務網點。

在質保方面,騰勢將為動力電池及關鍵零部件提供8年或15萬公里的保修期,為消費者提供無憂的售後保障服務。另外,騰勢還將開放新技術升級服務,騰勢車主可以進行軟體升級或部件升級。在移動應用方面,騰勢專屬App將提供更為智慧貼心的遠端操控功能,可實現智慧充電控制、車內設備控制、車輛狀態查詢以及一鍵尋車等功能。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務

iOS:應用程序擴展開發之Today擴展(Today Extesnsion)

一、簡介

iOS應用程序擴展是蘋果在iOS8推出的一個新特性,可以將自定義的功能和內容擴展到應用程序之外,在之後又經過不斷地優化和更新,已經成為開發中不可或缺的功能之一。擴展也是一個Target項目,它運行在主機應用程序上,可以與主機應用程序實現資源共享,和宿主應用程序的Target項目是彼此獨立的。系統提供的擴展有很多,Toady擴展就是其中之一,也被成為應用程序插件,它的作用是將今日發生的簡單消息展示在系統的插件界面上。Toady擴展模板名稱為Today Extension。圖1是創建Today擴展,圖2是擴展显示在插件界面上(可以通過點擊Edit來添加或者移除擴展)。 

 

二、創建

按照上圖1的方式創建一個Today Extension的Target后,系統會默認幫我們生成一個TodayViewController控制器類、MainInterface.storyBoard故事板、plist序列化文件,文件結構圖如下:

上圖中紅色圈內和箭頭指向的配置就是系統通過MainInterface.storyBoard幫我們實現了一個基本的Toady插件UI布局,運行后可以直接显示在插件界面上。可是,有的時候開發者並不想使用系統的故事板來構建UI,系統支持自定義的,我們只需要修改plist配置即可。具體的配置是這樣的:

[1] 將NSExtensionMainStoryboard字段刪除;

[2] 添加NSExtensionPrincipalClass字段,修改value為控制器的類名。 

[3] 在TodayViewController中的ViewDidLoad中設置preferredContentSize屬性大小,用來調整widget界面UI的尺寸。

配置如下圖所示:

//設置尺寸
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); 

  

三、分析

TodayViewController類比較簡單,就是一個VC類,它實現了系統提供的一個擴展協議<NCWidgetProviding>,可以在協議方法中實現對擴展的更新和狀態監控。

協議如下,都是可選的,開發者根據需要進行重寫。

//協議
@protocol NCWidgetProviding <NSObject>

@optional

//當數據更新時調用的方法,系統會定期更新擴展
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler;

//監聽显示模式(寬鬆型、緊奏型)和尺寸的改變,其中寬鬆和緊湊表示的是展開和摺疊狀態, iOS10開始才能使用
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize __API_AVAILABLE(ios(10.0));

//設置擴展UI邊距,注意:使用StoryBoard時,若要所見即所得,則這個方法中需要返回UIEdgeInsetsZero; (iOS10 and later 不會再被調用,棄用了)
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets __API_DEPRECATED("This method will not be called on widgets linked against iOS versions 10.0 and later.", ios(8.0, 10.0));

@end
//擴展,都是iOS10開始才能使用
@interface NSExtensionContext (NCWidgetAdditions)

//設置widget摺疊或展開狀態
@property (nonatomic, assign) NCWidgetDisplayMode widgetLargestAvailableDisplayMode __API_AVAILABLE(ios(10.0));

//只讀,widget狀態
@property (nonatomic, assign, readonly) NCWidgetDisplayMode widgetActiveDisplayMode __API_AVAILABLE(ios(10.0));

//獲取widget不同狀態的尺寸
- (CGSize)widgetMaximumSizeForDisplayMode:(NCWidgetDisplayMode)displayMode __API_AVAILABLE(ios(10.0));

@end

 

四、交互

Today擴展是寄宿於主機應用程序上的, TodayViewController又是一個UIViewController類,系統支持Today擴展對UIViewController進行切換。也就是說,蘋果在考慮提供給開發者在對UIViewController中添加各種展示控件這種便利的同時,也相應的提供給開發者通過Today擴展的widget從主機應用程序激活並打開宿主應用程序的機會。不過這個操作必須通過設置並調起scheme來實現。步驟如下:

[1] 配置宿主應用程序的scheme;

[2] 使用擴展的openURL打開宿主應用程序。

交互如下:

//擴展通過scheme打開主宿主應用程序
[self.extensionContext openURL:[NSURL URLWithString:@"MainApp://"] completionHandler:nil];

 

五、數據

既然Today擴展能與宿主應用程序進行交互,那麼肯定就存在數據通信的問題了。擴展與宿主目錄應用程序位於不同的目錄結構中,默認情況下,擴展與宿主應用程序的數據並不共享,代碼也不能復用。例如在宿主目錄應用程序中可能有網絡請求、數據持久化存儲等結構框架,在擴展中不可以直接使用,擴展需要提供自己的網絡請求框架、數據持久化框架等。這些問題蘋果都提供了解決方法,可以通過創建靜態庫的方式實現代碼共享,通過APP Group和Scheme跳轉實現數據共享。這裏主要講一下數據共享。注意:擴展和宿主應用程序的素材文件也是互相獨立的,必須將擴展中的素材添加到擴展Target。

方式一:通過配置scheme跳轉來實現數據共享。可以將傳遞的數據配置到URL中,然後宿主應用程序通過AppDeleagte的代理方法application:openURL:options:獲取數據,不過這個數據傳遞只能是單方向的。

 //打開主應用程序
-(void)openMainApp {
    
//共享數據
    NSString *schemeFormat = @"MainApp://action=openCarema?name=xiayuanquan";
    [self.extensionContext openURL:[NSURL URLWithString:schemeFormat] completionHandler:nil];
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    //從URL獲取共享數據,截取數據
    NSLog(@"---------url = %@---------",url);
    
    return YES;
}

方式二:給擴展的Target和宿主應用程序的Target項目都開啟APP Group,兩者配置相同的appgroupIndentifier標識,分別生成後綴名為.entitlements文件。然後對於小數據推薦使用偏好進行雙向傳遞共享數據,如圖所示。

//共享數據
//使用偏好設置
NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
[defalut setObject:@"xiayuanquan" forKey:@"name"];
//從偏好設置獲取共享數據
NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
NSString *name1 = [defalut objectForKey:@"name"];
NSLog(@"1------------name1=%@",name1);

方式三:配置跟方式二一樣,不過雙向傳遞共享數據使用文件目錄來實現。

//共享數據
//方式二:使用共享目錄
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:@"xiayuanquan" requiringSecureCoding:NO error:nil];
[data writeToURL:filePath atomically:YES];
//從共享目錄獲取共享數據
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
NSData *data = [NSData dataWithContentsOfURL:filePath];
NSLog(@"2------------data=%@",data);

 

六、適配

從iOS10開始,蘋果提供了NCWidgetDisplayMode展示模式,通過設置該模式來支持對widget進行摺疊和展開。在這裏,preferredContentSize就用到了。這個是用來設置widget的尺寸的。蘋果對widget的尺寸有自己的標準,width為maxSize.width,height取值範圍[110, maxSize.height]。這個maxSize可以在擴展協議<NCWidgetProviding>的協議方法也即widgetActiveDisplayModeDidChange:withMaximumSize中獲取:,可以發現每一種機型maxSize不一樣。

// 6s模擬器下:
// NCWidgetDisplayModeCompact模式下:{359.000000, 110.000000}
// NCWidgetDisplayModeExpanded模式下:{359.000000, 528.000000}

// 8 plus模擬器下:
// NCWidgetDisplayModeCompact模式下:{304.000000, 110.000000}
// NCWidgetDisplayModeExpanded模式下:{304.000000, 616.000000}

摺疊狀態:widget的高為110,此時設置preferredContentSize無效; 

展開狀態:widget的高為開發者設置的preferredContentSize.height,但是如果preferredContentSize.height>maxSize.height,此時取值為maxSize.height。 

適配iOS10,默認支持展開,設置如下: 

//設置widget默認為可以展開,此時處於摺疊狀態
#ifdef __IPHONE_10_0 //適配iOS10
   self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
#endif

 

七、範例

【去掉MainInterface.storyBoard,採用純代碼實現】

1、宿主應用程序AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //存儲共享數據
    //方式二:使用偏好設置
    NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
    [defalut setObject:@"xiayuanquan" forKey:@"name"];
    
    //存儲共享數據
    //方式三:使用共享目錄
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
    NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:@"xiayuanquan" requiringSecureCoding:NO error:nil];
    [data writeToURL:filePath atomically:YES];
    
    return YES;
}

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    //方式一:從URL獲取共享數據,例如參數
    NSLog(@"---------url = %@---------",url);
    
    return YES;
    
}

2、Widget擴展TodayViewController

//
//  TodayViewController.m
//  TodayExtension
//  Created by 夏遠全 on 2019/11/19.
//

#import "TodayViewController.h"
#import <NotificationCenter/NotificationCenter.h>

@interface TodayViewController () <NCWidgetProviding>

@end

@implementation TodayViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self config];
    [self createUI];
    [self fecthData];
}

//配置
-(void)config {
    
    self.view.backgroundColor = [UIColor lightGrayColor]; //widget背景色為灰色
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300); //widget尺寸大小, 寬度實際取maxSize,width,高度[110, maxSize.height]
    
    //設置widget默認為可以展開,此時處於摺疊狀態
    #ifdef __IPHONE_10_0 //適配iOS10
        self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
    #endif
    
}

//創建UI
-(void)createUI {
    
    CGFloat width = self.view.frame.size.width;
    CGFloat btnWidth = 100;
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake((width-btnWidth)/2, 0, btnWidth, 40)];
    button.backgroundColor = [UIColor greenColor];
    [button setTitle:@"OpenAPP" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(openMainApp) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}

//打開主應用程序
-(void)openMainApp {
    
    //傳遞共享數據
    //方式一:參數傳遞
    NSString *schemeFormat = @"MainApp://action=openCarema?name=xiayuanquan";
    [self.extensionContext openURL:[NSURL URLWithString:schemeFormat] completionHandler:nil];
    
}

//獲取共享數據
-(void)fecthData {
    
    //方式二:從偏好設置獲取共享數據
    NSUserDefaults *defalut = [[NSUserDefaults alloc] initWithSuiteName:@"group.xiayuanquan"];
    NSString *name1 = [defalut objectForKey:@"name"];
    NSLog(@"1------------name1=%@",name1);
    
    //方式三:從共享目錄獲取共享數據
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *baseURL = [fileManager containerURLForSecurityApplicationGroupIdentifier:@"group.xiayuanquan"];
    NSURL *filePath = [baseURL URLByAppendingPathComponent:@"file"];
    NSData *data = [NSData dataWithContentsOfURL:filePath];
    NSLog(@"2------------data=%@",data);
}

//當數據更新時調用的方法,系統會定期更新擴展
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    
    //獲取共享的數據,根據判斷回調對應的block
    //NCUpdateResultNewData,
    //NCUpdateResultNoData,
    //NCUpdateResultFailed
    
    completionHandler(NCUpdateResultNoData);
}


//監聽显示模式(寬鬆型、緊奏型)和尺寸的改變
//NCWidgetDisplayModeCompact :  摺疊
//NCWidgetDisplayModeExpanded : 展開
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    
    //maxSize:
    //雖說是最大的Size,但蘋果還是把Widget的高度範圍限制在了[110 ~ maxSize]之間
    //如果設置高度小於110,那麼default = 110;
    //如果設置高度大於開發者設置的preferredContentSize.Heiget,那麼default = maxSize;
    //摺疊狀態下,蘋果將高度固定為110,這個時候設置preferredContentSize屬性無效。
    NSLog(@"width = %lf-------height = %lf",maxSize.width,maxSize.height);
    
    //可以更改狀態
    if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);
    }
    else{
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 100);
    }
}

//設置擴展UI邊距,注意:使用StoryBoard時,若要所見即所得,則這個方法中需要返回UIEdgeInsetsZero; (iOS10 and later 不會再被調用)
//- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
//    return UIEdgeInsetsZero;
//}

@end

3、打印和gif

2019-11-20 16:22:31.074596+0800 TodayExtension[29668:1132736] 1------------name1=xiayuanquan
2019-11-20 16:22:31.234435+0800 TodayExtension[29668:1132736] 2------------data={length = 149, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 00000068 }
2019-11-20 16:22:31.234970+0800 TodayExtension[29668:1132736] maxSize.width = 359.000000-------maxSize.height = 110.000000 //摺疊
2019-11-20 16:22:38.117764+0800 TodayExtension[29668:1132736] maxSize.width = 359.000000-------maxSize.height = 528.000000 //展開

 

 

 

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

台灣海運大陸貨務運送流程

兩岸物流進出口一站式服務