1599008340
The age of AI is upon us and many companies begin to start their AI journey and reap the full potential of AI in their respective industries. But, some still consider AI as an immature technology with plenty of ways for it to go wrong. Therefore, before starting your long AI journey, there are some pitfalls you should avoid in implementing and developing AI solutions. They’re a result of the anecdotal, personal and published experience of AI projects that could have gone better.
Reinventing the wheel, that’s the reasonable words to describe building an AI system that has become an industry standard. It is a waste of your company’s time and resources. Instead, buy it from a company that has done research and development for years, and has launched a product that has been used and trusted by ample of users. Embrace their solution because this buy decision can get you high-quality AI services at a fraction of the cost and time that it would take to develop in-house. Because building an AI system in-house is a costly and risky endeavor, only do it if the AI system is quite specialized to your business and allow you to build a unique defensible advantage, something that can differentiate your company from its competitors.
#artificial-intelligence #software-development #machine-learning #deep-learning #data-science
1671543249
February 15, 2022 marked a significant milestone in Atlassian’s Server EOL (End Of Life) roadmap. This was not the final step. We still have two major milestones ahead of us: end of new app sales in Feb 2023, and end of support in Feb 2024. In simpler words, businesses still have enough time to migrate their Jira Server to one of the two available products – Atlassian Cloud or Atlassian DC. But the clock is ticking.
If we were to go by Atlassian numbers, 95% of their new customers choose cloud.
“About 80% of Fortune 500 companies have an Atlassian Cloud license. More than 90% of new customers choose cloud first.” – Daniel Scott, Product Marketing Director, Tempo
So that’s settled, right? We are migrating from Server to Cloud? And what about the solution fewer people talk about yet many users rely on – Jira DC?
Both are viable options and your choice will depend greatly on the needs of your business, your available resources, and operational processes.
Let’s start by taking a look at the functionality offered by Atlassian Cloud and Atlassian DC.
Feature | Atlassian Cloud | Atlassian Data Center |
Product Plans | Multiple plans | One plan |
Billing | Monthly and annual | Annual only |
Pricing model | Per user or tiered | Tiered only |
Support | Varying support levels depending on your plan: Enterprise support coverage is equivalent to Atlassian’s Data Center Premier Support offering | Varying support levels depending on the package: Priority Support or Premier Support (purchased separately) |
Total Cost of Ownership | TCO includes your subscription fee, plus product administration time | TCO includes your subscription fee and product administration time, plus: costs related to infrastructure provisioning or IaaS fees (for example, AWS costs) planned downtime time and resources needed for software upgrades |
Data encryption services | ||
Data residency services | ||
Audit logging | Organization-level audit logging available via Atlassian Access (Jira Software, Confluence) Product-level audit logs (Jira Software, Confluence) | Advanced audit logging |
Device security | Mobile device management support (Jira Software, Confluence, Jira Service Management) Mobile application management (currently on the roadmap) | Mobile device management support (Jira Software, Confluence, Jira Service Management) |
Content security | ||
Data Storage limits | 2 GB (Free) 250 GB (Standard) Unlimited storage (Premium and Enterprise) | No limits |
Performance | Continuous performance updates to improve load times, search responsiveness, and attachments Cloud infrastructure hosted in six geographic regions to reduce latency | Rate limitingCDN supports Smart mirrors and mirror farms (Bitbucket) |
Backup and data disaster recovery | Jira leverages multiple geographically diverse data centers, has a comprehensive backup program, and gains assurance by regularly testing their disaster recovery and business continuity plans. Backups are generated daily and retained for 30 days to allow for point-in-time data restoration | |
Containerization and orchestration | Docker images Kubernetes support (on the roadmap for now) | |
Change management and upgrades | Atlassian automatically handles software and security upgrades for you Sandbox instance to test changes (Premium and Enterprise) Release track options for Premium and Enterprise (Jira Software, Jira Service Management, Confluence) | |
Direct access to the database | No direct access to change the database structure, file system, or other server infrastructure Extensive REST APIs for programmatic data access | Direct database access |
Insights and reporting | Organization and admin insights to track adoption of Atlassian products, and evaluate the security of your organization. | Data Pipeline for advanced insightsConfluence analytics |
When talking about pros and cons, there’s always a chance that a competitive advantage for some is a dealbreaker for others. That’s why I decided to talk about pros and cons in matching pairs.
Pro: Scalability is one of the primary reasons businesses are choosing Jira Cloud. DC is technically also scalable, but you’ll need to scale on your own whereas the cloud version allows for the infrastructure to scale with your business.
Con: Despite the cloud’s ability to grow with your business, there is still a user limit of 35k users. In addition to that, the costs will grow alongside your needs. New users, licenses, storage, and computing power – all come at an additional cost. So, when your organization reaches a certain size, migrating to Jira DC becomes more cost-efficient.
Pro: Jira takes care of maintenance and support for you.
Con: Your business can suffer from unpredicted downtime. And there are certain security risks.
Pro: Extra bells and whistles:
Con: Most of these features are locked behind a paywall and are only available to either Premium and Enterprise or only Enterprise licenses (either fully or through addition of functionality. For example, Release tracks are only available to Enterprise customers.) In addition, the costs will grow as you scale the offering to fit your growing needs.
I’ll be taking the same approach to talking about the pros and cons as I did when writing about Atlassian Cloud. Pros and cons are paired.
Pro: Hosting your own system means you can scale horizontally and vertically through additional hardware. Extension of your systems is seamless, and there is no downtime (if you do everything correctly). Lastly, you don’t have to worry about the user limit – there is none.
Con: While having more control over your systems is great, it implies a dedicated staff of engineers, additional expenses on software licensing, hardware, and physical space. Moreover, seamless extension and 0% downtime are entirely on you.
Pro: Atlassian has updated the DC offering with native bundled applications such as Advanced Roadmaps, team calendars and analytics for confluence, insight asset management, and insight discovery in Jira Service Management DC.
Con: Atlassian has updated their pricing to reflect these changes. And you are still getting fewer “bells and whistles” than Jira Cloud users (as we can see from the feature comparison).
Pro: You are technically safer as the system is supported on your hardware by your specialists. Any and all Jira server issues, poor updates, and downtime are simply not your concern.
Con: Atlassian offers excellent security options: data encryption in transit and rest, to mobile app management, to audit offerings and API token controls. In their absence, your team company has to dedicate additional resources to security.
Pro: Additional benefits from Atlassian, such as the Priority Support bundle (all DC subscriptions have this option), and the Data center loyalty discount (more on that in the pricing section.)
Talking about pricing of SaaS products is always a challenge as there are always multiple tiers and various pay-as-you go features. Barebones Jira Cloud, for instance, is completely free of charge, yet there are a series of serious limitations.
Standard Jira Cloud will cost you an average of $7.50 per user per month while premium cranks that price up to $14.50. The Enterprise plan is billed annually and the cost is determined on a case-by-case basis. You can see the full comparison of Jira Cloud plans here. And you can use this online calculator to learn the cost of ownership in your particular case.
50 Users | Standard (Monthly/Annually) | Premium (Monthly/Annually) |
Jira Software | $387.50 / $3,900 | $762.50 / $7,650 |
Jira Work Management | $250 / $2,500 | |
Jira Service Management | $866.25 / $8,650 | $2,138.25 / $21,500 |
Confluence | $287.50 / $2,900 | $550 / $5,500 |
100 Users | Standard (Monthly/Annually) | Premium (Monthly/Annually) |
Jira Software | $775 / $7,750 | $1,525 / $15,250 |
Jira Work Management | $500 / $5,000 | |
Jira Service Management | $1,653.75 / $16,550 | $4,185.75 / $42,000 |
Confluence | $575 / $5,750 | $1,100 / $11,000 |
500 Users | Standard (Monthly/Annually) | Premium (Monthly/Annually) |
Jira Software | $3,140 / $31,500 | $5,107.50 / $51,000 |
Jira Work Management | $1,850 / $18,500 | |
Jira Service Management | $4,541.25 / $45,400 | $11,693.25 / $117,000 |
Confluence | $2,060 / $20,500 | $3,780 / $37,800 |
Please note that these prices were calculated without any apps included.
Jira Data Center starts at $42,000 per year and the plan includes up to 500 users. If you are a new client and are not eligible for any discounts*, here’s a chart that should give you an idea as to the cost of ownership of Jira DC. You can find more information regarding your specific case here.
Users | Commercial Annual Plan | Academic Annual Plan |
1-500 | USD 42,000 | USD 21,000 |
501-1000 | USD 72,000 | USD 36,000 |
1001-2000 | USD 120,000 | USD 60,000 |
Confluence for Data Center | ||
1-500 | USD 27,000 | USD 13,500 |
501-1000 | USD 48,000 | USD 24,000 |
1001-2000 | USD 84,000 | USD 42,000 |
Bitbucket for Data Center | ||
1-25 | USD 2,300 | USD 1,150 |
26-50 | USD 4,200 | USD 2,100 |
51-100 | USD 7,600 | USD 3,800 |
Jira Service Management for Data Center | ||
1-50 | USD 17,200 | USD 8,600 |
51-100 | USD 28,600 | USD 14,300 |
101-250 | USD 51,500 | USD 25,750 |
*Discounts:
Originally, there were several migration methods: Jira Cloud Migration Assistant, Jira Cloud Site Import, and there was an option to migrate via CSV export (though Jira actively discourages you from using this method). However, Jira’s team has focused their efforts on improving the Migration Assistant and have chosen to discontinue Cloud Site Import support.
Thanks to the broadened functionality of the assistant, it is now the only go-to method for migration with just one exception. If you are migrating over 1000 users and you absolutely need to migrate advanced roadmaps – you’ll need to rely on Site Import. At least for now, as Jira is actively working on implementing this feature in their assistant.
Here’s a quick comparison of the options and their limitations.
Features | Limitations | |
Cloud Migration Assistant | App migration Existing data on a Cloud Site is not overwritten You choose the projects, users, and groups you want to migrate Jira Service Management customer account migration Better UI to guide you through the migration Potential migration errors are displayed in advance Migration can be done in phases reducing the downtime Pre- and post-migration reports | You must be on a supported self-managed version of Jira |
Site Export | Can migrate Advanced Roadmaps | App data is not migrated Migration overrides existing data on the Cloud site Separate user importUsers from external directories are not migrated No choice of data you want or don’t want migrated There’s a need to split attachments into up to 5GB chunks Higher risks of downtime due to the “all or nothing” approach You must be on a supported self-managed version of Jira |
Pro tip: If you have a large base of users (above 2000), migrate them before you migrate projects and spaces. This way, you will not disrupt the workflow as users are still working on Server and the latter migration of data will take less time.
Now that we have settled on one particular offering based on available pricing models as well as the pros and the cons that matter the most to your organization, let’s talk about the “how”.
How does one migrate from Jira Server to Jira Cloud?
Jira’s Cloud Migration Assistant is a handy tool. It will automatically review your data for common errors. But it is incapable of doing all of the work for you. That’s why we – and Atlassian for that matter – recommend creating a pre-migration checklist.
Smart Checklist will help you craft an actionable, context-rich checklist directly inside a Jira ticket. This way, none of the tasks will be missed, lost, or abandoned.
Below is an example of how your migration checklist will look like in Jira.
Feel free to copy the code and paste it into your Smart Checklist editor and you’ll have the checklist at the ready.
# Create a user migration plan #must
> Please keep in mind that Jira Cloud Migration Assistant migrates all users and groups as well as users and groups related to selected projects
- Sync your user base
- Verify synchronization
- External users sync verification
- Active external directory verification
## Check your Jira Server version #must
- Verify via user interface or Support Zip Product Version Verification
> Jira Migration Assistant will not work unless Jira is running on a supported version
## Fix any duplicate email addresses #must
- Verify using SQL
> Duplicate email addresses are not supported by Jira Cloud and therefore can't be migrated with the Jira Cloud Migration Assistant. To avoid errors, you should find and fix any duplicate email addresses before migration. If user information is managed in an LDAP Server, you will need to update emails there and sync with Jira before the migration. If user information is managed locally, you can fix them through the Jira Server or Data Center user interface.
## Make sure you have the necessary permissions #must
- System Admin global permissions on the Server instance
- Exists in the target Cloud site
- Site Administrator Permission in the cloud
## Check for conflicts with group names #must
- Make sure that the groups in your Cloud Site don't have the same names as groups in Server
> Unless you are actively trying to merge them
- Delete or update add-on users so not to cause migration issues
- Verify via SQL
## Update firewall allowance rules #must
- None of the domains should be blocked by firewall or proxy
## Find a way to migrate apps #must
- Contact app vendors
## Check public access settings #must
- Projects
- Filters
- Filters
- Boards
- Dashboards
## Review server setup #mst
- at least 4gb Heap Allocation
- Open Files limit review
- Verify via support zip
## Check Server timezone #must for merging Cloud sites
- Switch to UTC is using any other timezone
> Add a system flag to the Jira Server instance -Duser.timezone=UTC as outlined in this article about updating documentation to include timezone details.
## Fix any duplicate shared configuration
## Storage limits
## Prepare the server instance
- Check data status
- All fields have value and are not null
-Any archived projects you wish to migrate are activated
## Prepare your cloud site
- Same Jira products enabled
- Same language
- User migration strategy
## Data backup
- Backup Jira Server site
- Backup Cloud site
## Run a test migration
- Done
## Notify Jira support
- Get in touch with Jira migration support
On the one hand, having all of your Jira products on a server may seem like a backup in and of itself. On the other hand, there are data migration best practices we should follow even if it’s just a precaution. No one has ever felt sorry for their data being too safe.
In addition, there are certain types of migration errors that can be resolved much faster with having a backup at hand.
Jira Cloud Migration Assistant is a free add-on Atlassian recommends using when migrating to the cloud. It accesses and evaluates your apps and helps migrate multiple projects.
Overall, the migration assistant offers a more stable and reliable migration experience. It automatically checks for certain errors. It makes sure all users have unique and valid emails, and makes sure that none of the project names and keys conflict with one another.
This is a step-by-step guide for importing your Jira Server data backup file into Jira Cloud.
Before we can proceed with the migration process, please make sure you meet the following prerequisites:
Once you are certain you are ready to migrate your Jira Server to Jira Data Center, you can proceed with an installation that’s much simpler than one would expect.
That’s it. You are all set. Well, unless your organization has specific needs such as continuous uptime, performance under heavy loads, and scalability, in which case you will need to set up a server cluster. You can find out more about setting up server clusters in this guide.
1635917640
このモジュールでは、Rustでハッシュマップ複合データ型を操作する方法について説明します。ハッシュマップのようなコレクション内のデータを反復処理するループ式を実装する方法を学びます。演習として、要求された注文をループし、条件をテストし、さまざまなタイプのデータを処理することによって車を作成するRustプログラムを作成します。
錆遊び場は錆コンパイラにブラウザインタフェースです。言語をローカルにインストールする前、またはコンパイラが利用できない場合は、Playgroundを使用してRustコードの記述を試すことができます。このコース全体を通して、サンプルコードと演習へのPlaygroundリンクを提供します。現時点でRustツールチェーンを使用できない場合でも、コードを操作できます。
Rust Playgroundで実行されるすべてのコードは、ローカルの開発環境でコンパイルして実行することもできます。コンピューターからRustコンパイラーと対話することを躊躇しないでください。Rust Playgroundの詳細については、What isRust?をご覧ください。モジュール。
このモジュールでは、次のことを行います。
Rustのもう1つの一般的なコレクションの種類は、ハッシュマップです。このHashMap<K, V>
型は、各キーK
をその値にマッピングすることによってデータを格納しますV
。ベクトル内のデータは整数インデックスを使用してアクセスされますが、ハッシュマップ内のデータはキーを使用してアクセスされます。
ハッシュマップタイプは、オブジェクト、ハッシュテーブル、辞書などのデータ項目の多くのプログラミング言語で使用されます。
ベクトルのように、ハッシュマップは拡張可能です。データはヒープに格納され、ハッシュマップアイテムへのアクセスは実行時にチェックされます。
次の例では、書評を追跡するためのハッシュマップを定義しています。ハッシュマップキーは本の名前であり、値は読者のレビューです。
use std::collections::HashMap;
let mut reviews: HashMap<String, String> = HashMap::new();
reviews.insert(String::from("Ancient Roman History"), String::from("Very accurate."));
reviews.insert(String::from("Cooking with Rhubarb"), String::from("Sweet recipes."));
reviews.insert(String::from("Programming in Rust"), String::from("Great examples."));
このコードをさらに詳しく調べてみましょう。最初の行に、新しいタイプの構文が表示されます。
use std::collections::HashMap;
このuse
コマンドは、Rust標準ライブラリの一部HashMap
からの定義をcollections
プログラムのスコープに取り込みます。この構文は、他のプログラミング言語がインポートと呼ぶものと似ています。
HashMap::new
メソッドを使用して空のハッシュマップを作成します。reviews
必要に応じてキーと値を追加または削除できるように、変数を可変として宣言します。この例では、ハッシュマップのキーと値の両方がString
タイプを使用しています。
let mut reviews: HashMap<String, String> = HashMap::new();
このinsert(<key>, <value>)
メソッドを使用して、ハッシュマップに要素を追加します。コードでは、構文は<hash_map_name>.insert()
次のとおりです。
reviews.insert(String::from("Ancient Roman History"), String::from("Very accurate."));
ハッシュマップにデータを追加した後、get(<key>)
メソッドを使用してキーの特定の値を取得できます。
// Look for a specific review
let book: &str = "Programming in Rust";
println!("\nReview for \'{}\': {:?}", book, reviews.get(book));
出力は次のとおりです。
Review for 'Programming in Rust': Some("Great examples.")
ノート
出力には、書評が単なる「すばらしい例」ではなく「Some( "すばらしい例。")」として表示されていることに注意してください。get
メソッドはOption<&Value>
型を返すため、Rustはメソッド呼び出しの結果を「Some()」表記でラップします。
この.remove()
メソッドを使用して、ハッシュマップからエントリを削除できます。get
無効なハッシュマップキーに対してメソッドを使用すると、get
メソッドは「なし」を返します。
// Remove book review
let obsolete: &str = "Ancient Roman History";
println!("\n'{}\' removed.", obsolete);
reviews.remove(obsolete);
// Confirm book review removed
println!("\nReview for \'{}\': {:?}", obsolete, reviews.get(obsolete));
出力は次のとおりです。
'Ancient Roman History' removed.
Review for 'Ancient Roman History': None
このコードを試して、このRustPlaygroundでハッシュマップを操作できます。
演習:ハッシュマップを使用して注文を追跡する
この演習では、ハッシュマップを使用するように自動車工場のプログラムを変更します。
ハッシュマップキーと値のペアを使用して、車の注文に関する詳細を追跡し、出力を表示します。繰り返しになりますが、あなたの課題は、サンプルコードを完成させてコンパイルして実行することです。
この演習のサンプルコードで作業するには、次の2つのオプションがあります。
ノート
サンプルコードで、
todo!
マクロを探します。このマクロは、完了するか更新する必要があるコードを示します。
最初のステップは、既存のプログラムコードを取得することです。
car_quality
、car_factory
およびmain
機能を。次のコードをコピーしてローカル開発環境で編集する
か、この準備されたRustPlaygroundでコードを開きます。
#[derive(PartialEq, Debug)]
struct Car { color: String, motor: Transmission, roof: bool, age: (Age, u32) }
#[derive(PartialEq, Debug)]
enum Transmission { Manual, SemiAuto, Automatic }
#[derive(PartialEq, Debug)]
enum Age { New, Used }
// Get the car quality by testing the value of the input argument
// - miles (u32)
// Return tuple with car age ("New" or "Used") and mileage
fn car_quality (miles: u32) -> (Age, u32) {
// Check if car has accumulated miles
// Return tuple early for Used car
if miles > 0 {
return (Age::Used, miles);
}
// Return tuple for New car, no need for "return" keyword or semicolon
(Age::New, miles)
}
// Build "Car" using input arguments
fn car_factory(order: i32, miles: u32) -> Car {
let colors = ["Blue", "Green", "Red", "Silver"];
// Prevent panic: Check color index for colors array, reset as needed
// Valid color = 1, 2, 3, or 4
// If color > 4, reduce color to valid index
let mut color = order as usize;
if color > 4 {
// color = 5 --> index 1, 6 --> 2, 7 --> 3, 8 --> 4
color = color - 4;
}
// Add variety to orders for motor type and roof type
let mut motor = Transmission::Manual;
let mut roof = true;
if order % 3 == 0 { // 3, 6, 9
motor = Transmission::Automatic;
} else if order % 2 == 0 { // 2, 4, 8, 10
motor = Transmission::SemiAuto;
roof = false;
} // 1, 5, 7, 11
// Return requested "Car"
Car {
color: String::from(colors[(color-1) as usize]),
motor: motor,
roof: roof,
age: car_quality(miles)
}
}
fn main() {
// Initialize counter variable
let mut order = 1;
// Declare a car as mutable "Car" struct
let mut car: Car;
// Order 6 cars, increment "order" for each request
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #2: Used, Convertible
order = order + 1;
car = car_factory(order, 2000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #3: New, Hard top
order = order + 1;
car = car_factory(order, 0);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #4: New, Convertible
order = order + 1;
car = car_factory(order, 0);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #5: Used, Hard top
order = order + 1;
car = car_factory(order, 3000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {:?}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
}
2. プログラムをビルドします。次のセクションに進む前に、コードがコンパイルされて実行されることを確認してください。
次の出力が表示されます。
1: Used, Hard top = true, Manual, Blue, 1000 miles
2: Used, Hard top = false, SemiAuto, Green, 2000 miles
3: New, Hard top = true, Automatic, Red, 0 miles
4: New, Hard top = false, SemiAuto, Silver, 0 miles
5: Used, Hard top = true, Manual, Blue, 3000 miles
6: Used, Hard top = true, Automatic, Green, 4000 miles
現在のプログラムは、各車の注文を処理し、各注文が完了した後に要約を印刷します。car_factory
関数を呼び出すたびにCar
、注文の詳細を含む構造体が返され、注文が実行されます。結果はcar
変数に格納されます。
お気づきかもしれませんが、このプログラムにはいくつかの重要な機能がありません。すべての注文を追跡しているわけではありません。car
変数は、現在の注文の詳細のみを保持しています。関数car
の結果で変数が更新されるたびcar_factory
に、前の順序の詳細が上書きされます。
ファイリングシステムのようにすべての注文を追跡するために、プログラムを更新する必要があります。この目的のために、<K、V>ペアでハッシュマップを定義します。ハッシュマップキーは、車の注文番号に対応します。ハッシュマップ値は、Car
構造体で定義されているそれぞれの注文の詳細になります。
main
関数の先頭、最初の中括弧の直後に次のコードを追加します{
。// Initialize a hash map for the car orders
// - Key: Car order number, i32
// - Value: Car order details, Car struct
use std::collections::HashMap;
let mut orders: HashMap<i32, Car> = HashMap;
2. orders
ハッシュマップを作成するステートメントの構文の問題を修正します。
ヒント
ハッシュマップを最初から作成しているので、おそらくこの
new()
メソッドを使用することをお勧めします。
3. プログラムをビルドします。次のセクションに進む前に、コードがコンパイルされていることを確認してください。コンパイラからの警告メッセージは無視してかまいません。
次のステップは、履行された各自動車注文をハッシュマップに追加することです。
このmain
関数では、car_factory
車の注文ごとに関数を呼び出します。注文が履行された後、println!
マクロを呼び出して、car
変数に格納されている注文の詳細を表示します。
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
新しいハッシュマップで機能するように、これらのコードステートメントを修正します。
car_factory
関数の呼び出しは保持します。返された各Car
構造体は、ハッシュマップの<K、V>ペアの一部として格納されます。println!
マクロの呼び出しを更新して、ハッシュマップに保存されている注文の詳細を表示します。main
関数で、関数の呼び出しcar_factory
とそれに伴うprintln!
マクロの呼び出しを見つけます。// Car order #1: Used, Hard top
car = car_factory(order, 1000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
println!("{}: {}, Hard top = {}, {:?}, {}, {} miles", order, car.age.0, car.roof, car.motor, car.color, car.age.1);
2. すべての自動車注文のステートメントの完全なセットを次の改訂されたコードに置き換えます。
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #2: Used, Convertible
order = order + 1;
car = car_factory(order, 2000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #3: New, Hard top
order = order + 1;
car = car_factory(order, 0);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #4: New, Convertible
order = order + 1;
car = car_factory(order, 0);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #5: Used, Hard top
order = order + 1;
car = car_factory(order, 3000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
orders(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
3. 今すぐプログラムをビルドしようとすると、コンパイルエラーが表示されます。<K、V>ペアをorders
ハッシュマップに追加するステートメントに構文上の問題があります。問題がありますか?先に進んで、ハッシュマップに順序を追加する各ステートメントの問題を修正してください。
ヒント
orders
ハッシュマップに直接値を割り当てることはできません。挿入を行うにはメソッドを使用する必要があります。
プログラムが正常にビルドされると、次の出力が表示されます。
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("Used", 1000) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 2000) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("New", 0) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("New", 0) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("Used", 3000) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 4000) })
改訂されたコードの出力が異なることに注意してください。println!
マクロディスプレイの内容Car
各値を示すことによって、構造体と対応するフィールド名。
次の演習では、ループ式を使用してコードの冗長性を減らします。
for、while、およびloop式を使用します
多くの場合、プログラムには、その場で繰り返す必要のあるコードのブロックがあります。ループ式を使用して、繰り返しの実行方法をプログラムに指示できます。電話帳のすべてのエントリを印刷するには、ループ式を使用して、最初のエントリから最後のエントリまで印刷する方法をプログラムに指示できます。
Rustは、プログラムにコードのブロックを繰り返させるための3つのループ式を提供します。
loop
:手動停止が発生しない限り、繰り返します。while
:条件が真のままで繰り返します。for
:コレクション内のすべての値に対して繰り返します。この単元では、これらの各ループ式を見ていきます。
loop
式は、無限ループを作成します。このキーワードを使用すると、式の本文でアクションを継続的に繰り返すことができます。ループを停止させるための直接アクションを実行するまで、アクションが繰り返されます。
次の例では、「We loopforever!」というテキストを出力します。そしてそれはそれ自体で止まりません。println!
アクションは繰り返し続けます。
loop {
println!("We loop forever!");
}
loop
式を使用する場合、ループを停止する唯一の方法は、プログラマーとして直接介入する場合です。特定のコードを追加してループを停止したり、Ctrl + Cなどのキーボード命令を入力してプログラムの実行を停止したりできます。
loop
式を停止する最も一般的な方法は、break
キーワードを使用してブレークポイントを設定することです。
loop {
// Keep printing, printing, printing...
println!("We loop forever!");
// On the other hand, maybe we should stop!
break;
}
プログラムがbreak
キーワードを検出すると、loop
式の本体でアクションの実行を停止し、次のコードステートメントに進みます。
break
キーワードは、特別な機能を明らかにするloop
表現を。break
キーワードを使用すると、式本体でのアクションの繰り返しを停止することも、ブレークポイントで値を返すこともできます。
次の例はbreak
、loop
式でキーワードを使用して値も返す方法を示しています。
let mut counter = 1;
// stop_loop is set when loop stops
let stop_loop = loop {
counter *= 2;
if counter > 100 {
// Stop loop, return counter value
break counter;
}
};
// Loop should break when counter = 128
println!("Break the loop at counter = {}.", stop_loop);
出力は次のとおりです。
Break the loop at counter = 128.
私たちのloop
表現の本体は、これらの連続したアクションを実行します。
stop_loop
変数を宣言します。loop
式の結果にバインドするようにプログラムに指示します。loop
式の本体でアクションを実行します:counter
値を現在の値の2倍にインクリメントします。counter
値を確認してください。counter
値が100以上です。ループから抜け出し、
counter
値を返します。
4. もしcounter
値が100以上ではありません。
ループ本体でアクションを繰り返します。
5. stop_loop
値を式のcounter
結果である値に設定しますloop
。
loop
式本体は、複数のブレークポイントを持つことができます。式に複数のブレークポイントがある場合、すべてのブレークポイントは同じタイプの値を返す必要があります。すべての値は、整数型、文字列型、ブール型などである必要があります。ブレークポイントが明示的に値を返さない場合、プログラムは式の結果を空のタプルとして解釈します()
。
while
ループは、条件式を使用しています。条件式が真である限り、ループが繰り返されます。このキーワードを使用すると、条件式がfalseになるまで、式本体のアクションを実行できます。
while
ループは、ブール条件式を評価することから始まります。条件式がと評価されるtrue
と、本体のアクションが実行されます。アクションが完了すると、制御は条件式に戻ります。条件式がと評価されるfalse
と、while
式は停止します。
次の例では、「しばらくループします...」というテキストを出力します。ループを繰り返すたびに、「カウントが5未満である」という条件がテストされます。条件が真のままである間、式本体のアクションが実行されます。条件が真でなくなった後、while
ループは停止し、プログラムは次のコードステートメントに進みます。
while counter < 5 {
println!("We loop a while...");
counter = counter + 1;
}
for
ループは、項目のコレクションを処理するためにイテレータを使用しています。ループは、コレクション内の各アイテムの式本体のアクションを繰り返します。このタイプのループの繰り返しは、反復と呼ばれます。すべての反復が完了すると、ループは停止します。
Rustでは、配列、ベクトル、ハッシュマップなど、任意のコレクションタイプを反復処理できます。Rustはイテレータを使用して、コレクション内の各アイテムを最初から最後まで移動します。
for
ループはイテレータとして一時変数を使用しています。変数はループ式の開始時に暗黙的に宣言され、現在の値は反復ごとに設定されます。
次のコードでは、コレクションはbig_birds
配列であり、イテレーターの名前はbird
です。
let big_birds = ["ostrich", "peacock", "stork"];
for bird in big_birds
iter()
メソッドを使用して、コレクション内のアイテムにアクセスします。for
式は結果にイテレータの現在の値をバインドするiter()
方法。式本体では、イテレータ値を操作できます。
let big_birds = ["ostrich", "peacock", "stork"];
for bird in big_birds.iter() {
println!("The {} is a big bird.", bird);
}
出力は次のとおりです。
The ostrich is a big bird.
The peacock is a big bird.
The stork is a big bird.
イテレータを作成するもう1つの簡単な方法は、範囲表記を使用することですa..b
。イテレータはa
値から始まりb
、1ステップずつ続きますが、値を使用しませんb
。
for number in 0..5 {
println!("{}", number * 2);
}
このコードは、0、1、2、3、および4の数値をnumber
繰り返し処理します。ループの繰り返しごとに、値を変数にバインドします。
出力は次のとおりです。
0
2
4
6
8
このコードを実行して、このRustPlaygroundでループを探索できます。
演習:ループを使用してデータを反復処理する
この演習では、自動車工場のプログラムを変更して、ループを使用して自動車の注文を反復処理します。
main
関数を更新して、注文の完全なセットを処理するためのループ式を追加します。ループ構造は、コードの冗長性を減らすのに役立ちます。コードを簡素化することで、注文量を簡単に増やすことができます。
このcar_factory
関数では、範囲外の値での実行時のパニックを回避するために、別のループを追加します。
課題は、サンプルコードを完成させて、コンパイルして実行することです。
この演習のサンプルコードで作業するには、次の2つのオプションがあります。
ノート
サンプルコードで、
todo!
マクロを探します。このマクロは、完了するか更新する必要があるコードを示します。
前回の演習でプログラムコードを閉じた場合は、この準備されたRustPlaygroundでコードを再度開くことができます。
必ずプログラムを再構築し、コンパイラエラーなしで実行されることを確認してください。
より多くの注文をサポートするには、プログラムを更新する必要があります。現在のコード構造では、冗長ステートメントを使用して6つの注文をサポートしています。冗長性は扱いにくく、維持するのが困難です。
ループ式を使用してアクションを繰り返し、各注文を作成することで、構造を単純化できます。簡略化されたコードを使用すると、多数の注文をすばやく作成できます。
main
機能、削除次の文を。このコードブロックは、order
変数を定義および設定し、自動車の注文のcar_factory
関数とprintln!
マクロを呼び出し、各注文をorders
ハッシュマップに挿入します。// Order 6 cars
// - Increment "order" after each request
// - Add each order <K, V> pair to "orders" hash map
// - Call println! to show order details from the hash map
// Initialize order variable
let mut order = 1;
// Car order #1: Used, Hard top
car = car_factory(order, 1000);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
...
// Car order #6: Used, Hard top
order = order + 1;
car = car_factory(order, 4000);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
2. 削除されたステートメントを次のコードブロックに置き換えます。
// Start with zero miles
let mut miles = 0;
todo!("Add a loop expression to fulfill orders for 6 cars, initialize `order` variable to 1") {
// Call car_factory to fulfill order
// Add order <K, V> pair to "orders" hash map
// Call println! to show order details from the hash map
car = car_factory(order, miles);
orders.insert(order, car);
println!("Car order {}: {:?}", order, orders.get(&order));
// Reset miles for order variety
if miles == 2100 {
miles = 0;
} else {
miles = miles + 700;
}
}
3. アクションを繰り返すループ式を追加して、6台の車の注文を作成します。order
1に初期化された変数が必要です。
4. プログラムをビルドします。コードがエラーなしでコンパイルされることを確認してください。
次の例のような出力が表示されます。
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
プログラムは現在、ループを使用して6台の車の注文を処理しています。6台以上注文するとどうなりますか?
main
関数のループ式を更新して、11台の車を注文します。 todo!("Update the loop expression to create 11 cars");
2. プログラムを再構築します。実行時に、プログラムはパニックになります!
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.26s
Running `target/debug/playground`
thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 4', src/main.rs:34:29
この問題を解決する方法を見てみましょう。
このcar_factory
関数では、if / else式を使用color
して、colors
配列のインデックスの値を確認します。
// Prevent panic: Check color index for colors array, reset as needed
// Valid color = 1, 2, 3, or 4
// If color > 4, reduce color to valid index
let mut color = order as usize;
if color > 4 {
// color = 5 --> index 1, 6 --> 2, 7 --> 3, 8 --> 4
color = color - 4;
}
colors
配列には4つの要素を持ち、かつ有効なcolor
場合は、インデックスの範囲は0〜3の条件式をチェックしているcolor
私たちはをチェックしません(インデックスが4よりも大きい場合color
、その後の関数で4に等しいインデックスへのときに我々のインデックスを車の色を割り当てる配列では、インデックス値から1を減算しますcolor - 1
。color
値4はcolors[3]
、配列と同様に処理されます。)
現在のif / else式は、8台以下の車を注文するときの実行時のパニックを防ぐためにうまく機能します。しかし、11台の車を注文すると、プログラムは9番目の注文でパニックになります。より堅牢になるように式を調整する必要があります。この改善を行うために、別のループ式を使用します。
car_factory
機能、ループ式であれば/他の条件文を交換してください。color
インデックス値が4より大きい場合に実行時のパニックを防ぐために、次の擬似コードステートメントを修正してください。// Prevent panic: Check color index, reset as needed
// If color = 1, 2, 3, or 4 - no change needed
// If color > 4, reduce to color to a valid index
let mut color = order as usize;
todo!("Replace `if/else` condition with a loop to prevent run-time panic for color > 4");
ヒント
この場合、if / else条件からループ式への変更は実際には非常に簡単です。
2. プログラムをビルドします。コードがエラーなしでコンパイルされることを確認してください。
次の出力が表示されます。
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
Car order 7: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
Car order 8: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 9: Some(Car { color: "Blue", motor: Automatic, roof: true, age: ("New", 0) })
Car order 10: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 11: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
このモジュールでは、Rustで使用できるさまざまなループ式を調べ、ハッシュマップの操作方法を発見しました。データは、キーと値のペアとしてハッシュマップに保存されます。ハッシュマップは拡張可能です。
loop
手動でプロセスを停止するまでの式は、アクションを繰り返します。while
式をループして、条件が真である限りアクションを繰り返すことができます。このfor
式は、データ収集を反復処理するために使用されます。
この演習では、自動車プログラムを拡張して、繰り返されるアクションをループし、すべての注文を処理しました。注文を追跡するためにハッシュマップを実装しました。
このラーニングパスの次のモジュールでは、Rustコードでエラーと障害がどのように処理されるかについて詳しく説明します。
リンク: https://docs.microsoft.com/en-us/learn/modules/rust-loop-expressions/
1625036303
Accelerate your digital transformation with our AI development services like media workflow automation, computer vision systems, video processing tools, and more. Our AI & ML team builds world-class AI solutions for startups, agencies, & enterprises catering to different verticals, like healthcare, adtech, eCommerce, etc.
Are you planning to outsource AI/ML development services? Or would you like to hire an offshore AI app development team?
Visit Website - https://www.valuecoders.com/ai-ml-development-services-company
#hireaidevelopers #aidevelopmentcompanies #ai development company #ai development services #artificial intelligence development company #ai services company
1619511840
If you were to ask any organization today, you would learn that they are all becoming reliant on Artificial Intelligence Solutions and using AI to digitally transform in order to bring their organizations into the new age. AI is no longer a new concept, instead, with the technological advancements that are being made in the realm of AI, it has become a much-needed business facet.
AI has become easier to use and implement than ever before, and every business is applying AI solutions to their processes. Organizations have begun to base their digital transformation strategies around AI and the way in which they conduct their business. One of these business processes that AI has helped transform is lead qualifications.
#ai-solutions-development #artificial-intelligence #future-of-artificial-intellige #ai #ai-applications #ai-trends #future-of-ai #ai-revolution
1619105520
If you’re looking to hire someone for artificial intelligence consulting services, you need to understand these 6 AI terms before you get started to get the most out of your consultations. Understanding these basic concepts will allow you to assist your developers in providing you the solution you are looking for. At the end of the day, working alongside your consultants is the best way to see the results you desire.
#artificial-intelligence #machine-learning-algorithms #ai-applications #ai-revolution #ai-driven-commerce #good-company #machine-learning #ai