1683847980
ChatGPT — это мощный инструмент для создания контента на естественном языке, который может помочь разработчикам интерфейса в создании интересных и удобных веб-сайтов. В этой статье вы прочтете несколько советов и тактик по использованию ChatGPT для создания контента для ваших проектов веб-дизайна. Вы узнаете, как:
Узнайте, как создавать контент для своих проектов веб-дизайна с помощью ChatGPT. Этот пост предоставит вам полную шпаргалку по использованию ChatGPT для дизайна внешнего интерфейса.
Создание контрольного списка внешнего интерфейса может помочь дизайнерам убедиться, что все соответствующие компоненты дизайна учтены. Дизайнеры могут просто создать полный контрольный список с помощью ChatGPT , который включает важные функции, такие как поток пользователей, доступность, цветовая схема, типографика, согласованность и удобство использования.
Быстрый
Create a checklist for frontend for a perfect [Screen] in a table
Например, предположим, что вы только что выпустили свой последний продукт, и хотя на бумаге он кажется успешным, вы не получаете ожидаемого взаимодействия. Вы качаете головой, недоумевая, почему пользователи не остаются. Это когда в игру вступает разработка пользовательского потока. Он содержит ключ к разгадке загадки того, как потребители взаимодействуют с вашим продуктом, помогая вам определить проблемные области и, в конечном итоге, улучшить общее впечатление от пользователя.
Вы можете узнать о целях, поведении и потенциальных препятствиях пользователя, наметив его путь. И вот как вы можете использовать ChatGPT:
Быстрый
Can you create user flow for a [app type]?
Дизайн-системы гарантируют единообразие, эффективность и качество дизайнерских работ, но их разработка сложна и требует много времени. Chat GPT поможет вам создать систему, соответствующую вашим требованиям, включая типографику, цветовые палитры, сетки макетов и значки.
Быстрый
Write a design system documentation for a [Frontend development Element]? Represent in a table with the states like default, clicked, hover, active, focus, and disabled. Describe these states with design token (color, font)
Chat GPT использует искусственный интеллект для создания палитры цветов, соответствующих индивидуальности и стилю вашего бренда, что экономит ваше время и энергию.
Быстрый
Can you suggest primary, secondary and tertiary colors for an [Website]? Represent in a table.
Создавая образы пользователей с помощью Chat GPT, вы можете проводить более успешные маркетинговые кампании и лучше понимать свою аудиторию. Узнайте больше о демографии, поведении и мотивах.
Быстрый
Can you create a user persona for an [Website]? Represent in a table.
Вам надоел стандартный текст веб-сайта, который не может увлечь вашу целевую аудиторию? Я был таким же, пока не попробовал Chat GPT. Теперь, когда я не использую Lorem Ipsums, я могу создавать лучше. Вы можете разрабатывать персонализированный и высококачественный контент, который точно соответствует вашему бренду и обращается к вашей целевой аудитории, используя возможности Chat GPT на основе искусственного интеллекта. Попробуйте это предложение, чтобы улучшить взаимодействие с пользователем вашего веб-сайта с помощью интригующего текста.
Быстрый
Generate 10 versions of 404 error message for a [Website].
Говорите с раздражающими клиентами
Теперь мы можем использовать Chat GPT для создания профессионального и конфиденциального сообщения, в котором кратко и прямо выражается их желание заплатить. Это действительно помогло мне справиться с некоторыми проблемными клиентами.
Быстрый
Negotiate with a client who hasn't paid me the final price despite the fact that the project has been completed. Can you create a message for me to send to him?
Также прочтите руководство по разработке базовых подсказок .
Эта статья поможет вам узнать о памятке Chat GPT для веб-дизайнеров. Мы верим, что это было полезно для вас. Пожалуйста, не стесняйтесь делиться своими мыслями и отзывами в разделе комментариев ниже.
Оригинальный источник статьи: https://www.cloudbooklet.com/
1683840600
ChatGPT 是一种强大的自然语言内容生成工具,可以帮助前端设计师创建有趣且用户友好的网站。在本文中,您将了解使用 ChatGPT 为您的网页设计项目制作内容的一些提示和策略。你会发现如何:
了解如何使用 ChatGPT 为您的网页设计项目制作内容。这篇文章将为您提供使用 ChatGPT 进行前端设计的完整备忘单。
创建前端设计清单可以帮助设计人员确保考虑到所有相关的设计组件。设计人员可以使用ChatGPT简单地创建一个完整的清单,其中包括用户流程、可访问性、配色方案、排版、一致性和可用性等重要功能。
迅速的
Create a checklist for frontend for a perfect [Screen] in a table
例如,假设您刚刚发布了最新产品,虽然表面上看起来很成功,但您没有收到预期的参与度。您摇摇头,对为什么用户不留下来感到困惑。这是开发用户流程发挥作用的时候。它是解开消费者如何使用您的产品之谜的关键,可帮助您识别痛点并最终改善整体用户体验。
您可以通过绘制用户路径来了解用户的目标、行为和潜在障碍。以下是使用 ChatGPT 的方法:
迅速的
Can you create user flow for a [app type]?
设计系统保证了设计工作的统一性、效率和质量,但开发一个系统既困难又耗时。Chat GPT 可以根据您的要求创建一个特定的系统来帮助您,包括排版、调色板、布局网格和图标。
迅速的
Write a design system documentation for a [Frontend development Element]? Represent in a table with the states like default, clicked, hover, active, focus, and disabled. Describe these states with design token (color, font)
Chat GPT 使用 AI 创建与您品牌的个性和风格相匹配的调色板,从而节省您的时间和精力。
迅速的
Can you suggest primary, secondary and tertiary colors for an [Website]? Represent in a table.
通过使用 Chat GPT 创建用户角色,您可以创建更成功的营销活动并更好地了解您的受众。详细了解人口统计数据、行为和动机。
迅速的
Can you create a user persona for an [Website]? Represent in a table.
您是否厌倦了无法吸引目标受众的通用网站文本?在尝试使用 Chat GPT 之前,我也是如此。现在我不使用 Lorem Ipsum 可以创造更好的作品。您可以使用 Chat GPT 的人工智能功能开发完全适合您的品牌并与您的目标受众交流的个性化和高质量内容。试试这个建议,通过有趣的文案来改善您网站的用户体验。
迅速的
Generate 10 versions of 404 error message for a [Website].
与烦人的客户交谈
我们现在可以利用 Chat GPT 来创建专业且敏感的消息,以简洁明了的方式表达他们的付款愿望。它确实帮助我处理了一些麻烦的客户。
迅速的
Negotiate with a client who hasn't paid me the final price despite the fact that the project has been completed. Can you create a message for me to send to him?
另请阅读基本提示工程指南。
本文旨在帮助您了解面向前端设计师的 Chat GPT 备忘单。我们相信它对您有所帮助。请随时在下面的评论部分分享您的想法和反馈。
文章原文出处:https: //www.cloudbooklet.com/
1683818843
ChatGPT is a powerful natural language content generation tool that may assist frontend designers in creating interesting and user-friendly websites. In this article, you’ll read over some tips and tactics for using ChatGPT to produce content for your web design projects. You will discover how to:
Learn how to produce content for your web design projects with ChatGPT. This post will provide you with a full cheat sheet for using ChatGPT for frontend design.
Creating a frontend design checklist may assist designers ensure that all relevant design components are taken into account. Designers may simply create a complete checklist using ChatGPT that includes important features such as user flow, accessibility, color scheme, typography, consistency, and usability.
Prompt
Create a checklist for frontend for a perfect [Screen] in a table
For example, suppose you’ve just released your latest product, and while it appears to be a success on paper, you’re not receiving the engagement you expected. You shake your head, puzzled as to why users aren’t staying. This is when developing a user flow comes into play. It holds the key to unravelling the enigma of how consumers engage with your product, assisting you in identifying pain areas and, eventually, improving the overall user experience.
You may learn about a user’s objectives, behaviors, and potential impediments by charting out their path. And here’s how you can put ChatGPT to use:
Prompt
Can you create user flow for a [app type]?
Design systems guarantee uniformity, efficiency, and quality in design work, but developing one is difficult and time-consuming. Chat GPT can assist you by creating a system specific to your requirements, including typography, color palettes, layout grids, and iconography.
Prompt
Write a design system documentation for a [Frontend development Element]? Represent in a table with the states like default, clicked, hover, active, focus, and disabled. Describe these states with design token (color, font)
Chat GPT uses AI to create a palette of colors that are matched to your brand’s personality and style, saving you time and energy.
Prompt
Can you suggest primary, secondary and tertiary colors for an [Website]? Represent in a table.
By creating user personas using Chat GPT, you can create more successful marketing campaigns and better understand your audience. Learn more about demographics, behaviors, and motives.
Prompt
Can you create a user persona for an [Website]? Represent in a table.
Are you fed up with generic website text that fails to captivate your target audience? I was the same way till I tried Chat GPT. I’m able to create better now that I’m not using Lorem Ipsums. You can develop personalized and high-quality content that exactly suits your brand and speaks to your target audience using Chat GPT’s AI-powered capabilities. Try this suggestion to improve the user experience of your website with intriguing copy.
Prompt
Generate 10 versions of 404 error message for a [Website].
Speak with annoying clients
We may now utilize Chat GPT to create a professional and sensitive message that expresses their desire for payment in a concise and straightforward way. It really helped me deal with some troublesome clients.
Prompt
Negotiate with a client who hasn't paid me the final price despite the fact that the project has been completed. Can you create a message for me to send to him?
Also Read Basic Prompt Engineering Guide.
This article is to help you learn about the Chat GPT cheatsheet for frontend designers. We trust that it has been helpful to you. Please feel free to share your thoughts and feedback in the comment section below.
Original article source at: https://www.cloudbooklet.com/
1678712946
GitHub CLI — это инструмент, позволяющий взаимодействовать с платформой GitHub с помощью интерфейса командной строки. Овладение наиболее часто используемыми командами позволит вам стать продуктивным сотрудником группы разработчиков, занимающихся наукой о данных, проектированием данных или машинным обучением.
Предельная скорость
Терминал (или оболочка, или интерфейс командной строки) — важный и часто упускаемый из виду инструмент для специалистов по данным. Это позволяет эффективно взаимодействовать с операционной системой без необходимости возиться с графическим интерфейсом, а также обеспечивает автоматизацию, планирование, гибкость и взаимодействие с приложениями и API, часто более прямым образом.
GitHub — еще один инструмент, который становится все более важным для специалистов по данным. GitHub в первую очередь предоставляет платформу для контроля версий и воспроизводимости. Это также позволяет разработчикам сотрудничать и обмениваться кодом и данными. По всем этим причинам GitHub стал неотъемлемой платформой специально для разработки программного обеспечения с открытым исходным кодом.
Неудивительно, что GitHub CLI — это инструмент GitHub, который позволяет взаимодействовать с платформой GitHub с помощью интерфейса командной строки. Овладение наиболее часто используемыми командами позволит вам стать продуктивным сотрудником команды разработчиков, будь то команда разработчиков веб-приложений или, что более конкретно для наших целей, группа инженеров по обработке данных, инженерии данных или машинному обучению.
Чтобы узнать больше об использовании интерфейса командной строки GitHub и получить удобную краткую справку, ознакомьтесь с нашей последней шпаргалкой .
GitHub CLI — это инструмент командной строки с открытым исходным кодом, который переносит GitHub на ваш терминал. Вы можете проверить статус, пул-реквесты, проблемы, файлы, суть и другие концепции GitHub.
Интерфейс командной строки GitHub не ограничивается командами рабочего процесса git; он позволяет вам выполнять все виды задач GitHub, не посещая сайт с помощью веб-браузера. Некоторые из общих задач, которые можно выполнить с помощью интерфейса командной строки GitHub, а также задачи, описанные в шпаргалке, включают:
Проверьте это сейчас и зайдите позже, чтобы узнать больше.
Оригинальный источник статьи: https://www.kdnuggets.com/
1678709160
GitHub CLI 是一种允许通过命令行界面与 GitHub 平台进行交互的工具。掌握最常用的命令将使您成为数据科学、数据工程或机器学习工程开发团队的高产。
终端速度
终端(或 shell,或命令行界面)是数据科学家重要且经常被忽视的工具。它允许与操作系统进行高效交互,而不必弄乱 GUI,并允许自动化、调度、灵活性以及通常以更直接的方式与应用程序和 API 交互。
GitHub 是另一个对数据科学家越来越重要的工具。GitHub 主要为版本控制和可重复性提供了一个平台。它还允许开发人员协作以及共享代码和数据。由于所有这些原因,GitHub 已成为专门用于开源软件开发的不可或缺的平台。
毫不奇怪,GitHub CLI 是允许使用命令行界面与 GitHub 平台进行交互的 GitHub 工具。掌握最常用的命令将使您成为开发团队的高效成员,无论是 Web 应用程序开发团队,还是更具体地针对我们的目的,数据科学、数据工程或机器学习工程团队。
有关使用 GitHub CLI 的更多信息,以及方便的快速参考,请查看我们最新的备忘单。
GitHub CLI 是一种开源命令行工具,可将 GitHub 带到您的终端。您可以检查状态、拉取请求、问题、文件、要点和其他 GitHub 概念。
GitHub CLI 不限于 git 工作流命令;它允许您执行各种 GitHub 任务,而无需使用 Web 浏览器访问该站点。可以通过 GitHub CLI 完成的一些常见任务以及备忘单中涵盖的任务包括:
立即查看,稍后再回来查看更多信息。
文章原文出处:https: //www.kdnuggets.com/
1678701780
The GitHub CLI is a tool that allows for interaction with the GitHub platform with the command line interface. Mastering the most-used commands will allow you to become a productive of a data science, data engineering, or machine learning engineering development team.
Terminal Velocity
The terminal (or shell, or command line interface) is an important and often overlooked tool for data scientists. It allows for efficient interaction with the operating system without having to mess with a GUI, and permits automation, scheduling, flexibility, and interaction with applications and APIs often in a more direct manner.
GitHub is another increasingly-vital tool for data scientists. GitHub primarily provides a platform for version control and reproducibility. It also allows for developer collaboration and the sharing of code and data. For all of these reason, GitHub has become an integral platform specifically for open source software development.
The GitHub CLI, unsurprisingly, is the GitHub tool that allows for interaction with the GitHub platform with the command line interface. Mastering the most-used commands will allow you to become a productive of a development team, be that a web app development team, or more specifically for our purposes, a data science, data engineering, or machine learning engineering team.
For more on using the GitHub CLI, and for a handy quick reference, check out our latest cheat sheet.
GitHub CLI is an open-source command line tool that brings GitHub to your terminal. You can check the status, pull requests, issues, files, gists, and other GitHub concepts.
The GitHub CLI isn't limited to git workflow commands; it allows you to perform all sorts of GitHub tasks without having to visit the site with a web browser. Some of the common tasks which can be accomplished via the GitHub CLI, and those covered in the cheat sheet, include:
Check it out now, and check back soon for more.
Original article source at: https://www.kdnuggets.com/
1677909840
The latest KDnuggets cheat sheet covers using ChatGPT to your advantage as a data scientist. It's time to master prompt engineering, and here is a handy reference for helping you along the way.
The Rise of ChatOps
You probably haven't heard of ChatGPT yet... 🙄
Aside from stealing your job, spreading lies, and plagiarizing on a mass scale (varying degrees of sarcasm intended for each of those common points of detraction), ChatGPT can also be very useful for the average data scientist in their day to day life.
The problem that we are currently grappling with is one of expectations: some expect that ChatGPT is nothing more than a stochastic parrot that produces rubbish and is completely useless, while others seem to think (either pessimistically or optimistically, depending on who you ask) that ChatGPT will be taking over the world, while either ridding us of monotony or laying waste to human civilization. If we all tempered our expectations and recognized this technology for what it is, and what it could be useful for, we would all be far better off. But in the era of outrage and hyperbole, nuance takes a back seat to hot takes. But I digress.
ChatGPT (and, indeed, the most robust and latest versions of GPT3) is meant to assist (that's right... assist!) humans that decide to use it as such, and with a little help from your friends at KDnuggets you will be able to hone your prompt engineering skills to do useful things like generate code, assist in your research process, and analyze data.
For more on ChatGPT for data science, check out our latest cheat sheet.
ChatGPT is a large language conversational AI built by OpenAI. It was trained using Reinforcement Learning from Human Feedback, similar to InstructGPT. ChatGPT understands the prompt and provides detailed repose that can help you with research, coding, and various data science tasks.
In this cheat sheet, Abid Ali Awan covers the following useful topics for data scientists using ChatGPT:
Bill Gates (among many, many others) has recognized that ChatGPT and related technologies are going to transform the world in which we live. But that's not necessarily a bad thing: if you learn to leverage and master ChatGPT and other LLM innovations in the same vein now, you are a step ahead of the game. Not learning how to use the machine is the greatest threat the machine poses to you or your career, so wrangle the robot now, and be a leader in these everchanging times.
Check it out now, and check back soon for more.
Original article source at: https://www.kdnuggets.com/
1677676688
Typing Objects
Object
Versus object
Object
is the type of all instances of class Object
.
const obj1 = {};
obj1 instanceof Object; // true
obj1.toString === Object.prototype.toString; // true
function fn(x: Object) {}
fn("foo"); // OK
object
is the type of all non-primitive values.
function fn(x: object) {}
fn("foo"); // Error: "foo" is a primitive
interface ExampleInterface {
myProperty: boolean; // Property signature
myMethod(x: string): void; // Method signature, 'x' for documentation only
[prop: string]: any; // Index signature
(x: number): string; // Call signature
new (x: string): ExampleInstance; // Construct signature
readonly modifierOne: string; // readonly modifier
modifierTwo?: string; // optional modifier
}
Helps to describe Arrays or objects that are used as dictionaries.
interface I1 {
[key: string]: boolean;
// 'number' is not assignable to string index type 'boolean'
myProp: number;
// '() => string' is not assignable to string index type 'boolean'
myMethod(): string;
}
interface I2 {
[key: string]: number;
myProp: number; // OK
}
Enables interfaces to describe functions, this
is the optional calling context of the function in this example:
interface ClickListener {
(this: Window, e: MouseEvent): void;
}
const myListener: ClickListener = e => {
console.log("mouse clicked!", e);
};
addEventListener("click", myListener);
Enables describing classes and constructor functions. A class has two types:
The constructor sits in the static side, when a class implements an interface, only the instance side of the class is checked.
interface ClockInterface {
tick(): void;
}
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
// Using Class Expression
const ClockA: ClockConstructor = class Clock implements ClockInterface {
constructor(h: number, m: number) {}
tick() {}
};
const clockClassExpression = new ClockA(18, 11);
// Using Class Declaration with a Constructor Function
class ClockB implements ClockInterface {
constructor(h: number, m: number) {}
tick() {}
}
function createClock(
ctor: ClockConstructor,
hour: number,
minute: number
): ClockInterface {
return new ctor(hour, minute);
}
const clockClassDeclaration = createClock(ClockB, 12, 17);
Typically used in the signature of a higher-order function.
type MyFunctionType = (name: string) => number;
Engineers can’t just think of interfaces as “objects that have exactly a set of properties” or “objects that have at least a set of properties”. In-line object arguments receive an additional level of validation that doesn’t apply when they’re passed as variables.
TypeScript is a structurally typed language. To create a Dog
you don’t need to explicitly extend the Dog
interface, any object with a breed
property that is of type string
can be used as a Dog
:
interface Dog {
breed: string;
}
function printDog(dog: Dog) {
console.log("Dog: " + dog.breed);
}
const ginger = {
breed: "Airedale",
age: 3
};
printDog(ginger); // excess properties are OK!
printDog({
breed: "Airedale",
age: 3
});
// Excess properties are NOT OK!!
// Argument of type '{ breed: string; age: number; }' is not assignable...
Mapped Types - Getting Types from Data
typeof
/ keyof
Examplesconst data = {
value: 123,
text: "text",
subData: {
value: false
}
};
type Data = typeof data;
// type Data = {
// value: number;
// text: string;
// subData: {
// value: boolean;
// }
const data = ["text 1", "text 2"] as const;
type Data = typeof data[number]; // "text 1" | "text 2"
const locales = [
{
locale: "se",
language: "Swedish"
},
{
locale: "en",
language: "English"
}
] as const;
type Locale = typeof locales[number]["locale"]; // "se" | "en"
const currencySymbols = {
GBP: "£",
USD: "$",
EUR: "€"
};
type CurrencySymbol = keyof typeof currencySymbols; // "GBP" | "USD" | "EUR"
keyof
with Generics and Interfaces Exampleinterface HasPhoneNumber {
name: string;
phone: number;
}
interface HasEmail {
name: string;
email: string;
}
interface CommunicationMethods {
email: HasEmail;
phone: HasPhoneNumber;
fax: { fax: number };
}
function contact<K extends keyof CommunicationMethods>(
method: K,
contact: CommunicationMethods[K] // turning key into value - a mapped type
) {
//...
}
contact("email", { name: "foo", email: "mike@example.com" });
contact("phone", { name: "foo", phone: 3213332222 });
contact("fax", { fax: 1231 });
// // we can get all values by mapping through all keys
type AllCommKeys = keyof CommunicationMethods;
type AllCommValues = CommunicationMethods[keyof CommunicationMethods];
Immutability
readonly
PropertiesProperties marked with readonly
can only be assigned to during initialization or from within a constructor of the same class.
type Point = {
readonly x: number;
readonly y: number;
};
const origin: Point = { x: 0, y: 0 }; // OK
origin.x = 100; // Error
function moveX(p: Point, offset: number): Point {
p.x += offset; // Error
return p;
}
function moveX(p: Point, offset: number): Point {
// OK
return {
x: p.x + offset,
y: p.y
};
}
readonly
Class PropertiesGettable area property is implicitly read-only because there’s no setter:
class Circle {
readonly radius: number;
constructor(radius: number) {
this.radius = radius;
}
get area() {
return Math.PI * this.radius ** 2;
}
}
readonly
Array / Tupleconst array: readonly string[];
const tuple: readonly [string, string];
const
Assertionsnumber
becomes number literal// Type '10'
let x = 10 as const;
readonly
tuples// Type 'readonly [10, 20]'
let y = [10, 20] as const;
readonly
properties"hello"
to string
)// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;
const
contexts don’t immediately convert an expression to be fully immutable.let arr = [1, 2, 3, 4];
let foo = {
name: "foo",
contents: arr
} as const;
foo.name = "bar"; // Error
foo.contents = []; // Error
foo.contents.push(5); // OK
Strict Mode
strict: true /* Enable all strict type-checking options. */
is equivalent to enabling all of the strict mode family options:
noImplicitAny: true /* Raise error on expressions and declarations with an implied 'any' type */,
strictNullChecks: true /* Enable strict null checks */,
strictFunctionTypes: true /* Enable strict checking of function types */,
strictBindCallApply: true /* Enable strict 'bind', 'call', and 'apply' methods on functions */,
strictPropertyInitialization: true /* Enable strict checking of property initialization in classes */,
noImplicitThis: true /* Raise error on 'this' expressions with an implied 'any' type */,
alwaysStrict: true /* Parse in strict mode and emit "use strict" for each source file */
You can then turn off individual strict mode family checks as needed.
--strictNullChecks
In strict null checking mode, null
and undefined
are no longer assignable to every type.
let name: string;
name = "Marius"; // OK
name = null; // Error
name = undefined; // Error
let name: string | null;
name = "Marius"; // OK
name = null; // OK
name = undefined; // Error
Optional parameter ?
automatically adds | undefined
type User = {
firstName: string;
lastName?: string; // same as `string | undefined`
};
undefined
.?
to the end of parameters we want to be optional. This is different from adding | undefined
which requires the parameter to be explicitly passed as undefined
function fn1(x: number | undefined): void {
x;
}
function fn2(x?: number): void {
x;
}
fn1(); // Error
fn2(); // OK
fn1(undefined); // OK
fn2(undefined); // OK
Type guard needed to check if Object is possibly null
:
function getLength(s: string | null) {
// Error: Object is possibly 'null'.
return s.length;
}
function getLength(s: string | null) {
if (s === null) {
return 0;
}
return s.length;
}
// JS's truthiness semantics support type guards in conditional expressions
function getLength(s: string | null) {
return s ? s.length : 0;
}
function doSomething(callback?: () => void) {
// Error: Object is possibly 'undefined'.
callback();
}
function doSomething(callback?: () => void) {
if (typeof callback === "function") {
callback();
}
}
--strictBindCallApply
The
call()
method calls a function with a giventhis
value and arguments provided individually, whileapply()
accepts a single array of arguments. Thebind()
method creates a new function.
When set, TypeScript will check that the built-in methods of functions call
, bind
, and apply
are invoked with correct argument for the underlying function:
function fn(x: string) {
return parseInt(x);
}
const n1 = fn.call(undefined, "10"); // OK
const n2 = fn.call(undefined, false); // `false` is not assignable to parameter of type `string`
--strictPropertyInitialization
Verify that each instance property declared in a class either:
// Error
class User {
// 'username' has no initializer & not definitely assigned in constructor
username: string;
}
// OK
class User {
username = "n/a";
}
const user = new User();
const username = user.username.toLowerCase();
// OK
class User {
constructor(public username: string) {}
}
const user = new User("mariusschulz");
const username = user.username.toLowerCase();
class User {
username: string | undefined;
}
const user = new User();
// Whenever we want to use the username property as a string, we first have
// to make sure that it actually holds a string, not the value undefined
const username =
typeof user.username === "string" ? user.username.toLowerCase() : "n/a";
Types
never
never
represents the type of values that never occur. It is used in the following two places:
never
can be used in control flow analysis:
function controlFlowAnalysisWithNever(value: string | number) {
if (typeof value === "string") {
value; // Type string
} else if (typeof value === "number") {
value; // Type number
} else {
value; // Type never
}
}
unknown
unknown
is the type-safe counterpart of the any
type: we have to do some form of checking before performing most operations on values of type unknown
.
JSON
from localStorage
using unknown
Exampletype Result =
| { success: true; value: unknown }
| { success: false; error: Error };
function tryDeserializeLocalStorageItem(key: string): Result {
const item = localStorage.getItem(key);
if (item === null) {
// The item does not exist, thus return an error result
return {
success: false,
error: new Error(`Item with key "${key}" does not exist`)
};
}
let value: unknown;
try {
value = JSON.parse(item);
} catch (error) {
// The item is not valid JSON, thus return an error result
return {
success: false,
error
};
}
// Everything's fine, thus return a success result
return {
success: true,
value
};
}
Generics
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString"); // Type of output is 'string'
let output = identity("myString"); // The compiler sets the value of `T`
function makePair<F, S>() {
let pair: { first: F; second: S };
function getPair() {
return pair;
}
function setPair(x: F, y: S) {
pair = {
first: x,
second: y
};
}
return { getPair, setPair };
}
const { getPair, setPair } = makePair<number, string>(); // Creates a pair
setPair(1, "y"); // Must pass (number, string)
Parameters<T>
and ReturnType<T>
function logDuration<T extends (...args: any[]) => any>(func: T) {
const funcName = func.name;
// Return a new function that tracks how long the original took
return (...args: Parameters<T>): ReturnType<T> => {
console.time(funcName);
const results = func(...args);
console.timeEnd(funcName);
return results;
};
}
function addNumbers(a: number, b: number): number {
return a + b;
}
// Hover over is `addNumbersWithLogging: (a: number, b: number) => number`
const addNumbersWithLogging = logDuration(addNumbers);
addNumbersWithLogging(5, 3);
ConstructorParameters<T>
and InstanceType<T>
class Hero {
constructor(public point: [number, number]) {}
}
const entities = [];
const entityFactory = <
T extends {
new (...args: any[]): any;
}
>(
classToCreate: T,
numberOf: number,
...args: ConstructorParameters<T>
): InstanceType<T>[] =>
[...Array(numberOf)].map(() => new classToCreate(...args));
entities.push(...entityFactory(Hero, 10, [12, 10]));
Discriminated Unions
A data structure used to hold a value that could take on several different, but fixed, types.
never
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
interface Triangle {
kind: "triangle";
whatever: number;
}
type Shape = Square | Rectangle | Circle | Triangle;
function assertNever(x: never): never {
throw new Error("Unexpected object: " + x);
}
function area(s: Shape) {
switch (s.kind) {
case "square":
return s.size * s.size;
case "rectangle":
return s.height * s.width;
case "circle":
return Math.PI * s.radius ** 2;
default:
return assertNever(s); // Error
// Argument of type 'Triangle' not assignable to param of type 'never'
}
}
Optional Chaining
?.
returns undefined
when hitting a null
or undefined
Album where the artist, and the artists biography might not be present in the data.
type AlbumAPIResponse = {
title: string;
artist?: {
name: string;
bio?: string;
previousAlbums?: string[];
};
};
// Instead of:
const maybeArtistBio = album.artist && album.artist.bio;
// ?. acts differently than && on "falsy" values: empty string, 0, NaN, false
const artistBio = album?.artist?.bio;
// optional chaining also works with the [] operators when accessing elements
const maybeArtistBioElement = album?.["artist"]?.["bio"];
const maybeFirstPreviousAlbum = album?.artist?.previousAlbums?.[0];
Optional chaining on an optional function:
interface OptionalFunction {
bar?: () => number;
}
const foo: OptionalFunction = {};
const bat = foo.bar?.(); // number | undefined
Nullish Coalescing
??
“fall Backs” to a Default Value When Dealing with null
or undefined
Value foo
will be used when it’s “present”; but when it’s null
or undefined
, calculate bar()
in its place.
let x = foo ?? bar();
// instead of
let x = foo !== null && foo !== undefined ? foo : bar();
It can replace uses of ||
when trying to use a default value, and avoids bugs. When localStorage.volume
is set to 0
, the page will set the volume to 0.5
which is unintended. ??
avoids some unintended behaviour from 0
, NaN
and ""
being treated as falsy values.
function initializeAudio() {
const volume = localStorage.volume || 0.5; // Potential bug
}
Assertion Functions
Assertions in JavaScript are often used to guard against improper types being passed in.
Assert()
Doesn’t Work for Type Checkingfunction yell(str) {
assert(typeof str === "string");
return str.toUppercase(); // Oops! We misspelled 'toUpperCase'
}
if
and typeof
Everywhere is Bloatfunction yell(str) {
if (typeof str !== "string") {
throw new TypeError("str should have been a string.");
}
// Error caught!
return str.toUppercase();
}
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg);
}
}
function yell(str) {
assert(typeof str === "string");
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property 'toUppercase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?
}
Very similar to writing type predicate signatures.
function assertIsString(val: any): asserts val is string {
if (typeof val !== "string") {
throw new AssertionError("Not a string!");
}
}
function yell(str: any) {
assertIsString(str);
// Now TypeScript knows that 'str' is a 'string'.
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property 'toUppercase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?
}
Mike North - TypeScript 3 Fundamentals v2
Shu Uesugi - TypeScript for Beginner Programmers
Author: David-Else
Source Code: https://github.com/David-Else/modern-typescript-with-examples-cheat-sheet
License: GPL-3.0 license
1677103620
An intuitive guide that will help you to prepare and preprocess your dataset before applying the machine learning model.
Data cleaning is a very important and critical step in your data science project. The success of the machine model depends on how you preprocess the data. If you underestimate and skip the preprocessing of your dataset, the model won’t perform well and you’ll lose a lot of time searching to understand why it doesn’t work as well as you would expect.
Lately, I began to create cheat sheets to speed up my data science activities, in particular a summary with the basics of data cleaning. In this post and cheat sheet, I am going to show five different aspects that characterize the preprocessing steps in your data science project.
In this cheat sheet, we go from detecting and handling missing data, dealing with duplicates and finding solutions to duplicates, outlier detection, label encoding and one-hot-encoding of categorical features, to transformations, such as MinMax normalization and standard normalization. Moreover, this guide exploits the methods provided by three of the most popular Python libraries, Pandas, Scikit-Learn and Seaborn for displaying plots.
Learning these python tricks will help you to extract more information as possible from the dataset and, consequently, the machine learning model will be able to perform better by learning from a clean and preprocessed input.
Original article source at: https://www.kdnuggets.com/
1673428588
Cheat-Sheet Collection for DevOps, Engineers, IT and more
Nginx is open source software for web serving, reverse proxying, caching, load balancing, media streaming, and more.
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers.
Ansible is the simplest way to automate apps and IT infrastructure.
Python is an interpreted, high-level, general-purpose programming language.
Go also known as Golang, is a statically typed, compiled programming language designed at Google.
Git is the open source distributed version control system that facilitates GitHub activities on your laptop or desktop.
Regular expression also known as Regex is a special text string for describing a search pattern.
PowerShell is a task automation and configuration management framework from Microsoft.
VIM aka Vi IMproved
is a highly configurable text editor for efficiently creating and changing any kind of text.
Jenkins an open source automation server which enables developers around the world to reliably build, test, and deploy their software.
CI/CD Continuous Integration and Continuous Delivery (CI/CD) have made the practice of software development increasingly complex—and overwhelming.
Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.
Linux
Redis is an in-memory data structure store, used as a database, cache and message broker.
Slack is a messaging tool for making communication fast and easy. It lets you share messages and files with your team, organized by channel.
Puppet lets you automate the enforcement, security, and delivery of your hybrid or cloud-native infrastructure.
Google Cloud Developer builds scalable and highly available applications using Google recommended practices and tools that leverage fully managed services.
AI, Neural Networks, Machine Learning, Deep Learning & Data Science is intelligence demonstrated by machines.
PostgreSQL is a free and open-source relational database management system (RDBMS) emphasizing extensibility and SQL compliance.
Ajax AJAX = Asynchronous JavaScript And XML.
Amazon Web Services (AWS) is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered pay-as-you-go basis.
Infrastructure as code (IaC), is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.
Author: sk3pp3r
Source Code: https://github.com/sk3pp3r/cheat-sheet-pdf
License: MIT license
1673146440
Want to help improve this? File an issue or open a pull request! :)
This is not meant to be a beginner's guide or a detailed discussion about Swift; it is meant to be a quick reference to common, high level topics.
Note: This was written this fairly quickly, mostly to teach myself Swift, so it still needs a lot of love and there are important sections still missing. Please feel free to edit this document to update or improve upon it, making sure to keep with the general formatting of the document. The list of contributors can be found here.
If something isn't mentioned here, it's probably covered in detail in one of these:
Comments should be used to organize code and to provide extra information for future refactoring or for other developers who might be reading your code. Comments are ignored by the compiler so they do not increase the compiled program size.
Two ways of commenting:
// This is an inline comment
/* This is a block comment
and it can span multiple lines. */
// You can also use it to comment out code
/*
func doWork() {
// Implement this
}
*/
Using MARK
to organize your code:
// MARK: - Use mark to logically organize your code
// Declare some functions or variables here
// MARK: - They also show up nicely in the properties/functions list in Xcode
// Declare some more functions or variables here
Using FIXME
to remember to fix your code:
// Some broken code might be here
// FIXME: Use fixme to create a reminder to fix broken code later
FIXME
works a lot like MARK
because it makes organizing code easier, but it's used exclusively when you need to remember to fix something.
Using TODO
to remember to add, delete, or generally refactor your code:
// Some incomplete code might be here
// TODO: Use todo to create a reminder to finish things up later
TODO
is very similar to FIXME
and MARK
, but it's used exclusively when you need to remember to add, delete, or change your code later.
Auto-generating method documentation: In a method's preceding line, press ⌥ Option + ⌘ Command + /
to automatically generate a documentation stub for your method.
Permissible sizes of data types are determined by how many bytes of memory are allocated for that specific type and whether it's a 32-bit or 64-bit environment. In a 32-bit environment, long
is given 4 bytes, which equates to a total range of 2^(4*8)
(with 8 bits in a byte) or 4294967295
. In a 64-bit environment, long
is given 8 bytes, which equates to 2^(8*8)
or 1.84467440737096e19
.
For a complete guide to 64-bit changes, please see the transition document.
Unless you have a good reason to use C primitives, you should just use the Swift types to ensure compability going foward.
In fact, Swift just aliases C types to a Swift equivalent:
// C char is aliased as an Int8 and unsigned as UInt8
let aChar = CChar()
let anUnsignedChar = CUnsignedChar()
print("C char size: \(MemoryLayout.size(ofValue: aChar)) with min: \(Int8.min) and max: \(Int8.max)")
// C char size: 1 with min: -128 and max: 127
print("C unsigned char size: \(MemoryLayout.size(ofValue: anUnsignedChar)) with min: \(UInt8.min) and max: \(UInt8.max)")
// C unsigned char size: 1 with min: 0 and max: 255
// C short is aliased as an Int16 and unsigned as UInt16
let aShort = CShort()
let unsignedShort = CUnsignedShort()
print("C short size: \(MemoryLayout.size(ofValue: aShort)) with min: \(Int16.min) and max: \(Int16.max)")
// C short size: 2 with min: -32768 and max: 32767
print("C unsigned short size: \(MemoryLayout.size(ofValue: unsignedShort)) with min: \(UInt16.min) and max: \(UInt16.max)")
// C unsigned short size: 2 with min: 0 and max: 65535
// C int is aliased as an Int32 and unsigned as UInt32
let anInt = CInt()
let unsignedInt = CUnsignedInt()
print("C int size: \(MemoryLayout.size(ofValue: anInt)) with min: \(Int32.min) and max: \(Int32.max)")
// C int size: 4 with min: -2147483648 and max: 2147483647
print("C unsigned int size: \(MemoryLayout.size(ofValue: unsignedInt)) with min: \(UInt32.min) and max: \(UInt32.max)")
// C unsigned int size: 4 with min: 0 and max: 4294967295
// C long is aliased as an Int and unsigned as UInt
let aLong = CLong()
let unsignedLong = CUnsignedLong()
print("C long size: \(MemoryLayout.size(ofValue: aLong)) with min: \(Int.min) and max: \(Int.max)")
// C long size: 8 with min: -9223372036854775808 and max: 9223372036854775807
print("C unsigned long size: \(MemoryLayout.size(ofValue: unsignedLong)) with min: \(UInt.min) and max: \(UInt.max)")
// C unsigned long size: 8 with min: 0 and max: 18446744073709551615
// C long long is aliased as an Int64 and unsigned as UInt64
let aLongLong = CLongLong()
let unsignedLongLong = CUnsignedLongLong()
print("C long long size: \(MemoryLayout.size(ofValue: aLongLong)) with min: \(Int64.min) and max: \(Int64.max)")
// C long long size: 8 with min: -9223372036854775808 and max: 9223372036854775807
print("C unsigned long long size: \(MemoryLayout.size(ofValue: unsignedLongLong)) with min: \(UInt64.min) and max: \(UInt64.max)")
// C unsigned long long size: 8 with min: 0 and max: 18446744073709551615
From the docs:
C Type | Swift Type |
---|---|
bool | CBool |
char, signed char | CChar |
unsigned char | CUnsignedChar |
short | CShort |
unsigned short | CUnsignedShort |
int | CInt |
unsigned int | CUnsignedInt |
long | CLong |
unsigned long | CUnsignedLong |
long long | CLongLong |
unsigned long long | CUnsignedLongLong |
wchar_t | CWideChar |
char16_t | CChar16 |
char32_t | CChar32 |
float | CFloat |
double | CDouble |
Integers can be signed or unsigned. When signed, they can be either positive or negative and when unsigned, they can only be positive.
Apple states: Unless you need to work with a specific size of integer, always use Int
for integer values in your code. This aids code consistency and interoperability. Even on 32-bit platforms, Int
[...] is large enough for many integer ranges.
Fixed width integer types with their accompanying byte sizes as the variable names:
// Exact integer types
let aOneByteInt: Int8 = 127
let aOneByteUnsignedInt: UInt8 = 255
let aTwoByteInt: Int16 = 32767
let aTwoByteUnsignedInt: UInt16 = 65535
let aFourByteInt: Int32 = 2147483647
let aFourByteUnsignedInt: UInt32 = 4294967295
let anEightByteInt: Int64 = 9223372036854775807
let anEightByteUnsignedInt: UInt64 = 18446744073709551615
// Minimum integer types
let aTinyInt: Int8 = 127
let aTinyUnsignedInt: UInt8 = 255
let aMediumInt: Int16 = 32767
let aMediumUnsignedInt: UInt16 = 65535
let aNormalInt: Int32 = 2147483647
let aNormalUnsignedInt: UInt32 = 4294967295
let aBigInt: Int64 = 9223372036854775807
let aBigUnsignedInt: UInt64 = 18446744073709551615
// The largest supported integer type
let theBiggestInt: IntMax = 9223372036854775807
let theBiggestUnsignedInt: UIntMax = 18446744073709551615
Floats cannot be signed or unsigned.
// Single precision (32-bit) floating-point. Use it when floating-point values do not require 64-bit precision.
let aFloat = Float()
print("Float size: \(MemoryLayout.size(ofValue: aFloat))")
// Float size: 4
// Double precision (64-bit) floating-point. Use it when floating-point values must be very large or particularly precise.
let aDouble = Double()
print("Double size: \(MemoryLayout.size(ofValue: aDouble))")
// Double size: 8
// Boolean
let isBool: Bool = true // Or false
In Objective-C comparative statements, 0
and nil
were considered false
and any non-zero/non-nil values were considered true
. However, this is not the case in Swift. Instead, you'll need to directly check their value such as if x == 0
or if object != nil
nil : Used to specify a null object pointer. When classes are first initialized, all properties of the class point to nil
.
Enumeration types can be defined as follows:
// Specifying a typed enum with a name (recommended way)
enum UITableViewCellStyle: Int {
case default, valueOne, valueTwo, subtitle
}
// Accessing it:
let cellStyle: UITableViewCellStyle = .default
As of Swift 3, all enum options should be named in lowerCamelCased.
Newer Swift versions have a nice substitute for the old NS_OPTIONS
macro for creating bitmasks to compare to.
An example for posterity:
struct Options: OptionSet {
let rawValue: Int
init(rawValue: Int) {
self.rawValue = rawValue
}
init(number: Int) {
self.init(rawValue: 1 << number)
}
static let OptionOne = Options(number: 0)
static let OptionTwo = Options(number: 1)
static let OptionThree = Options(number: 2)
}
let options: Options = [.OptionOne, .OptionTwo]
options.contains(.OptionOne) // true
options.contains(.OptionThree) // false
Sometimes it is necessary to cast an object into a specific class or data type. Examples of this would be casting from a Float
to an Int
or from a UITableViewCell
to a subclass such as RPTableViewCell
.
Swift uses is
and as
both for checking object types as well as conformance to a given protocol.
Checking object type using is
:
if item is Movie {
movieCount += 1
print("It is a movie.")
} else if item is Song {
songCount += 1
print("It is a song.")
}
The is
operator returns true
if an instance is of that object type, or conforms to the specified protocol, and returns false
if it does not.
If you want to be able to easily access the data during one of these checks, you can use as?
to optionally (or as!
to force) unwrap the object when necessary:
for item in library {
if let movie = item as? Movie {
print("Director: \(movie.director)")
} else if let song = item as? Song {
print("Artist: \(song.artist)")
}
}
The as?
version of the downcast operator returns an optional value of the object or protocol's type, and this value is nil
if the downcast fails or this instance does not conform to the specified protocol.
The as!
version of the downcast operator forces the downcast to the specified object or protocol type and triggers a runtime error if the downcast does not succeed.
If you're working with AnyObject
objects given from the Cocoa API, you can use:
for movie in someObjects as! [Movie] {
// do stuff
}
If given an array with Any
objects, you can use a switch
statement with the type defined for each case
:
var things = [Any]()
for thing in things {
switch thing {
case 0 as Int:
print("Zero as an Int")
case let someString as! String:
print("S string value of \"\(someString)\"")
case let (x, y) as! (Double, Double):
print("An (x, y) point at \(x), \(y)")
case let movie as! Movie:
print("A movie called '\(movie.name)' by director \(movie.director)")
default:
print("Didn't match any of the cases specified")
}
}
Swift also offers some simple methods of casting between it's given data types.
// Example 1:
let aDifferentDataType: Float = 3.14
let anInt: Int = Int(aDifferentDataType)
// Example 2:
let aString: String = String(anInt)
Swift supports most standard C operators and improves several capabilities to eliminate common coding errors. The assignment operator =
does not return a value, to prevent it from being mistakenly used when the equal to operator ==
is intended.
Arithmetic operators (+
, -
, *
, /
, %
) detect and disallow value overflow, to avoid unexpected results when working with numbers that become larger or smaller than the allowed value range of the type that stores them.
Operator | Purpose |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Remainder |
Operator | Purpose |
---|---|
== | Equal to |
=== | Identical to |
!= | Not equal to |
!== | Not identical to |
~= | Pattern match |
> | Greater than |
< | Less than |
>= | Greater than or equal to |
<= | Less than or equal to |
Operator | Purpose |
---|---|
= | Assign |
+= | Addition |
-= | Subtraction |
*= | Multiplication |
/= | Division |
%= | Remainder |
&= | Bitwise AND |
|= | Bitwise Inclusive OR |
^= | Exclusive OR |
<<= | Shift Left |
>>= | Shift Right |
Operator | Purpose |
---|---|
! | NOT |
&& | Logical AND |
|| | Logical OR |
Operator | Purpose |
---|---|
..< | Half-open range |
... | Closed range |
Operator | Purpose |
---|---|
& | Bitwise AND |
| | Bitwise Inclusive OR |
^ | Exclusive OR |
~ | Unary complement (bit inversion) |
<< | Shift Left |
>> | Shift Right |
Typically, assigning or incrementing an integer, float, or double past it's range would result in a runtime error. However, if you'd instead prefer to safely truncate the number of available bits, you can opt-in to have the variable overflow or underflow using the following operators:
Operator | Purpose |
---|---|
&+ | Addition |
&- | Subtraction |
&* | Multiplication |
Example for unsigned integers (works similarly for signed):
var willOverflow = UInt8.max
// willOverflow equals 255, which is the largest value a UInt8 can hold
willOverflow = willOverflow &+ 1
// willOverflow is now equal to 0
var willUnderflow = UInt8.min
// willUnderflow equals 0, which is the smallest value a UInt8 can hold
willUnderflow = willUnderflow &- 1
// willUnderflow is now equal to 255
Operator | Purpose |
---|---|
?? | Nil coalescing |
?: | Ternary conditional |
! | Force unwrap object value |
? | Safely unwrap object value |
Swift allows you to overwrite existing operators or define new operators for existing or custom types. For example, this is why in Swift you can join strings using the +
operator, even though it is typically used for math.
Operator overloading is limited to the following symbols, / = - + * % < > ! & | ^ . ~
, however you cannot overload the =
operator by itself (it must be combined with another symbol).
Operators can be specified as:
prefix
: goes before an object such as -negativeNumber
infix
: goes between two objects, such as a + b
postfix
: goes after an object, such as unwrapMe!
Examples:
struct Vector2D: CustomStringConvertible {
var x = 0.0, y = 0.0
var description: String {
return "Vector2D(x: \(x), y: \(y))"
}
}
infix operator +-: AdditionPrecedence
extension Vector2D {
static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector is a Vector2D instance with values of (4.0, -2.0)
Classes are typically declared using separate .swift
files, but multiple classes can also be created within the same file if you'd like to organize it that way.
Unlike Objective-C, there's no need for an interface file (.h
) in Swift.
The implementation file should contain (in this order):
import
statementsclass
declaration which contains any constants or variables necessary for the classExample:
MyClass.swift
import UIKit
class MyClass {
// Declare any constants or variables at the top
let kRPErrorDomain = "com.myIncredibleApp.errors"
var x: Int, y: Int
// Use mark statements to logically organize your code
// MARK: - Class Methods, e.g. MyClass.functionName()
class func alert() {
print("This is a class function.")
}
// MARK: - Instance Methods, e.g. myClass.functionName()
init(x: Int, y: Int) {
self.x = x
self.y = y
}
// MARK: - Private Methods
private func pointLocation() -> String {
return "x: \(x), y: \(y)"
}
}
When you want to create a new instance of a class, you use the syntax:
let myClass = MyClass(x: 1, y: 2)
where x
and y
are variables that are passed in at the time of instantiation.
More info here in the docs.
Swift doesn't come with a preprocessor so it only supports a limited number of statements for build time. Things like #define
have been replaced with global constants defined outside of a class.
Directive | Purpose |
---|---|
#if | An if conditional statement |
#elif | An else if conditional statement |
#else | An else conditional statement |
#endif | An end if conditional statement |
Directive | Purpose |
---|---|
import | Imports a framework |
Directive | Purpose |
---|---|
let | Declares local or global constant |
var | Declares a local or global variable |
class | Declares a class-level constant or variable |
static | Declares a static type |
Directive | Purpose |
---|---|
typealias | Introduces a named alias of an existing type |
enum | Introduces a named enumeration |
struct | Introduces a named structure |
class | Begins the declaration of a class |
init | Introduces an initializer for a class, struct or enum |
init? | Produces an optional instance or an implicitly unwrapped optional instance; can return nil |
deinit | Declares a function called automatically when there are no longer any references to a class object, just before the class object is deallocated |
func | Begins the declaration of a function |
protocol | Begins the declaration of a formal protocol |
static | Defines as type-level within struct or enum |
convenience | Delegate the init process to another initializer or to one of the class’s designated initializers |
extension | Extend the behavior of class, struct, or enum |
subscript | Adds subscripting support for objects of a particular type, normally for providing a convenient syntax for accessing elements in a collective, list or sequence |
override | Marks overriden initializers |
Directive | Purpose |
---|---|
operator | Introduces a new infix, prefix, or postfix operator |
Directive | Purpose |
---|---|
dynamic | Marks a member declaration so that access is always dynamically dispatched using the Objective-C runtime and never inlined or devirtualized by the compiler |
final | Specifies that a class can’t be subclassed, or that a property, function, or subscript of a class can’t be overridden in any subclass |
lazy | Indicates that the property’s initial value is calculated and stored at most once, when the property is first accessed |
optional | Specifies that a protocol’s property, function, or subscript isn’t required to be implemented by conforming members |
required | Marks the initializer so that every subclass must implement it |
weak | Indicates that the variable or property has a weak reference to the object stored as its value |
Directive | Purpose |
---|---|
open | Can be subclassed outside of its own module and its methods overridden as well; truly open to modification by others and useful for framework builders |
public | Can only be subclassed by its own module or have its methods overridden by others within the same module |
internal | (Default) Indicates the entities are only available to the entire module that includes the definition, e.g. an app or framework target |
fileprivate | Indicates the entities are available only from within the source file where they are defined |
private | Indicates the entities are available only from within the declaring scope within the file where they are defined (e.g. within the { } brackets only) |
Literals are compiler directives which provide a shorthand notation for creating common objects.
Syntax | What it does |
---|---|
"string" | Returns a String object |
28 | Returns an Int |
3.14 , 0xFp2 , 1.25e2 | Returns a Double object |
true , false | Returns a Bool object |
[] | Returns an Array object |
[keyName:value] | Returns a Dictionary object |
0b | Returns a binary digit |
0o | Returns an octal digit |
0x | Returns a hexadecimal digit |
Special characters can be included:
\0
\\
(can be used to escape a double quote)\t
\n
\r
\"
\'
\u{n}
where n is between one and eight hexadecimal digitslet example = [ "hi", "there", 23, true ]
print("item at index 0: \(example[0])")
let example = [ "hi" : "there", "iOS" : "people" ]
if let value = example["hi"] {
print("hi \(value)")
}
For mutable literals, declare it with var
; immutable with let
.
Functions without a return type use this format:
// Does not return anything or take any arguments
func doWork() {
// Code
}
class
precedes declarations of class functions:
// Call on a class, e.g. MyClass.someClassFunction()
class func someClassFunction() {
// Code
}
static
is similar to class functions where you don't need an instance of the class or struct in order to call a method on it:
// Call on a class/struct, e.g. MyStruct.someStaticFunction()
static func someStaticFunction() {
// Code
}
Declare instance functions:
// Called on an instance of a class, e.g. myClass.someInstanceFunction()
func doMoreWork() {
// Code
}
Function arguments are declared within the parentheses:
// Draws a point
func draw(point: CGPoint)
Return types are declared as follows:
// Returns a String object for the given String argument
func sayHelloToMyLilFriend(lilFriendsName: String) -> String {
return "Oh hello, \(lilFriendsName). Cup of tea?"
}
You can have multiple return values, referred to as a tuple:
// Returns multiple objects
func sayHelloToMyLilFriend(lilFriendsName: String) -> (msg: String, nameLength: Int) {
return ("Oh hello, \(lilFriendsName). Cup of tea?", countElements(lilFriendsName))
}
var hello = sayHelloToMyLilFriend("Rob")
print(hello.msg) // "Oh hello, Rob. Cup of tea?"
print(hello.nameLength) // 3
And those multiple return values can be optional:
func sayHelloToMyLilFriend(lilFriendsName: String) -> (msg: String, nameLength: Int)?
By default, external parameter names are given when you call the function, but you can specify that one or more are not shown in the method signature by putting a _
symbol in front of the parameter name:
func sayHelloToMyLilFriend(_ lilFriendsName: String) {
// Code
}
sayHelloToMyLilFriend("Rob")
or you can rename the variable once within the method scope:
func sayHelloToMyLilFriend(friendsName lilFriendsName: String) {
// Code
}
sayHelloToMyLilFriend(friendsName: "Rob") // and local variable is `lilFriendsName`
You can also specify default values for the parameters:
func sayHelloToMyLilFriend(_ lilFriendsName: String = "Rob") {
// Code
}
sayHelloToMyLilFriend() // "Oh hello, Rob. Cup of tea?"
sayHelloToMyLilFriend("Jimbob") // "Oh hello, Jimbob. Cup of tea?"
Swift also supports variadic parameters so you can have an open-ended number of parameters passed in:
func sayHelloToMyLilFriends(_ lilFriendsName: String...) {
// Code
}
sayHelloToMyLilFriends("Rob", "Jimbob", "Cletus")
// "Oh hello, Rob, Jimbob and Cletus. Cup of tea?"
And lastly, you can also use a prefix to declare input parameters as inout
.
An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.
You may remember inout
parameters from Objective-C where you had to sometimes pass in an &error
parameter to certain methods, where the &
symbol specifies that you're actually passing in a pointer to the object instead of the object itself. The same applies to Swift's inout
parameters now as well.
Functions are called using dot syntax: myClass.doWork()
or self.sayHelloToMyLilFriend("Rob Phillips")
self
is a reference to the function's containing class.
At times, it is necessary to call a function in the superclass using super.someMethod()
.
Declaring a constant or variable allows you to maintain a reference to an object within a class or to pass objects between classes.
Constants are defined with let
and variables with var
. By nature, constants are obviously immutable (i.e. cannot be changed once they are instantiated) and variables are mutable.
class MyClass {
let text = "Hello" // Constant
var isComplete: Bool // Variable
}
There are many ways to declare properties in Swift, so here are a few examples:
var myInt = 1 // inferred type
var myExplicitInt: Int = 1 // explicit type
var x = 1, y = 2, z = 3 // declare multiple variables
let (a,b) = (1,2) // declare multiple constants
The default access level for constants and variables is internal
:
class MyClass {
// Internal (default) properties
var text: String
var isComplete: Bool
}
To declare them publicly or openly, they should also be within a public
or open
class as shown below:
public class MyClass {
// Public properties
public var text: String
public let x = 1
}
// Or
open class MyClass {
// Public properties
open var text: String
open let x = 1
}
File private variables and constants are declared with the fileprivate
directive:
class MyClass {
// Private properties
fileprivate var text: String
fileprivate let x = 1
}
In Objective-C, variables were backed by getters, setters, and private instance variables created at build time. However, in Swift getters and setters are only used for computed properties and constants actually don't have a getter or setter at all.
The getter is used to read the value, and the setter is used to write the value. The setter clause is optional, and when only a getter is needed, you can omit both clauses and simply return the requested value directly. However, if you provide a setter clause, you must also provide a getter clause.
You can overrride the getter and setter of a property to create the illusion of the Objective-C property behavior, but you'd need to store them as a private property with a different name (not recommended for most scenarios):
private var _x: Int = 0
var x: Int {
get {
print("Accessing x...")
return _x
}
set {
print("Setting x...")
_x = newValue
}
}
Swift also has callbacks for when a property will be or was set using willSet
and didSet
shown below:
var numberOfEdits = 0
var value: String = "" {
willSet {
print("About to set value...")
}
didSet {
numberOfEdits += 1
}
}
Properties can be accessed using dot notation:
myClass.myVariableOrConstant
self.myVariable // Self is optional here except within closure scopes
Local variables and constants only exist within the scope of a function.
func doWork() {
let localStringVariable = "Some local string variable."
self.doSomething(string: localStringVariable)
}
The general rule of thumb: Clarity and brevity are both important, but clarity should never be sacrificed for brevity.
These both use camelCase
where the first letter of the first word is lowercase and the first letter of each additional word is capitalized.
These both use CapitalCase
where the first letter of every word is capitalized.
The options in an enum should be lowerCamelCased
These should use verbs if they perform some action (e.g. performInBackground
). You should be able to infer what is happening, what arguments a function takes, or what is being returned just by reading a function signature.
Example:
// Correct
func move(from start: Point, to end: Point) {}
// Incorrect (likely too expressive, but arguable)
func moveBetweenPoints(from start: Point, to end: Point) {}
// Incorrect (not expressive enough and lacking argument clarity)
func move(x: Point, y: Point) {}
Closures in Swift are similar to blocks in Objective-C and are essentially chunks of code, typically organized within a {}
clause, that are passed between functions or to execute code as a callback within a function. Swift's func
functions are actually just a special case of a closure in use.
{ (params) -> returnType in
statements
}
// Map just iterates over the array and performs whatever is in the closure on each item
let people = ["Rob", "Jimbob", "Cletus"]
people.map({
(person: String) -> String in
"Oh hai, \(person)..."
})
// Oh hai, Rob
// Oh hai, Jimbob
// Oh hai, Cletus
// Closure for alphabetically reversing an array of names, where sorted is a Swift library function
let names = ["Francesca", "Joe", "Bill", "Sally", ]
var reversed = names.sorted { (s1: String, s2: String) -> Bool in
return s1 > s2
}
// Or on a single line:
reversed = names.sorted{ (s1: String, s2: String) -> Bool in return s1 > s2 }
// Or because Swift can infer the Bool type:
reversed = names.sorted { s1, s2 in return s1 > s2 }
// Or because the return statement is implied:
reversed = names.sorted { s1, s2 in s1 > s2 }
// Or even shorter using shorthand argument names, such as $0, $1, $2, etc.:
reversed = names.sorted { $0 > $1 }
// Or just ridiculously short because Swift's String greater-than operator implementation exactly matches this function definition:
reversed = names.sorted(by: >)
If the closure is the last parameter to the function, you can also use the trailing closure pattern. This is especially useful when the closure code is especially long and you'd like some extra space to organize it:
func someFunctionThatTakesAClosure(closure: () -> ()) {
// function body goes here
}
// Instead of calling like this:
someFunctionThatTakesAClosure({
// closure's body goes here
})
// You can use trailing closure like this:
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
A closure can capture constants and variables from the surrounding context in which it is defined. The closure can then refer to and modify the values of those constants and variables from within its body, even if the original scope that defined the constants and variables no longer exists.
In Swift, the simplest form of a closure that can capture values is a nested function, written within the body of another function. A nested function can capture any of its outer function’s arguments and can also capture any constants and variables defined within the outer function.
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
Swift determines what should be captured by reference and what should be copied by value. You don’t need to annotate a variable to say that they can be used within the nested function. Swift also handles all memory management involved in disposing of variables when they are no longer needed by the function.
If you create a closure that references self.*
it will capture self
and retain a strong reference to it. This is sometimes the intended behavior, but often could lead to retain cycles where both objects won't get deallocated at the end of their lifecycles.
The two best options are to use unowned
or weak
. This might look a bit messy, but saves a lot of headache.
Use unowned
when you know the closure will only be called if self
still exists, but you don't want to create a strong (retain) reference.
Use weak
if there is a chance that self
will not exist, or if the closure is not dependent upon self
and will run without it. If you do use weak
also remember that self
will be an optional variable and should be checked for existence.
typealias SomeClosureType = (_ value: String) -> ()
class SomeClass {
fileprivate var currentValue = ""
init() {
someMethod { (value) in // Retained self
self.currentValue = value
}
someMethod { [unowned self] (value) in // Not retained, but expected to exist
self.currentValue = value
}
someMethod { [weak self] value in // Not retained, not expected to exist
// Or, alternatively you could do
guard let sSelf = self else { return }
// Or, alternatively use `self?` without the guard
sSelf.currentValue = value
}
}
func someMethod(closure: SomeClosureType) {
closure("Hai")
}
}
Reference: Apple: Automatic Reference Counting
Coming soon…
Swift uses all of the same control statements that other languages have:
if someTestCondition {
// Code to execute if the condition is true
} else if someOtherTestCondition {
// Code to execute if the other test condition is true
} else {
// Code to execute if the prior conditions are false
}
As you can see, parentheses are optional.
The shorthand notation for an if-else
statement is a ternary operator of the form: someTestCondition ? doIfTrue : doIfFalse
Example:
func stringForTrueOrFalse(trueOrFalse: Bool) -> String {
return trueOrFalse ? "True" : "False"
}
In Swift, we need to consider the use of optional
values. One very basic way to handle nil
cases is with an if-else
statement:
func stringForOptionalExistence(optionalValue: String?) -> String {
if optionalValue != nil {
return optionalValue
} else {
return "Empty"
}
}
In this particular case, we are returning optionalValue
if it is not nil
, and "Empty"
if optionalValue
is nil
. The shorthand notation for this type of if(!=nil)-else
statement is a nil coalescing operator of the form: optionalValue ?? nonOptionalValue
Example:
func stringForOptionalExistence(optionalValue: String?) -> String {
return optionalValue ?? "Empty"
}
Swift enables you to use ranges inside of for
loops now:
for index in 1...5 {
print("\(index) times 5 is \(index * 5)")
}
// Or if you don't need the value of the index
let base = 3, power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
print("\(base) to the power of \(power) is \(answer)")
// prints "3 to the power of 10 is 59049"
// We explicitly cast to the Movie class from AnyObject class
for movie in someObjects as [Movie] {
// Code to execute each time
}
// Enumerating simple array
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
print("Hello, \(name)!")
}
// Enumerating simple dictionary
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
If you need to cast to a certain object type, see the earlier discussion about the as!
and as?
keywords.
while someTestCondition {
// Code to execute while the condition is true
}
repeat {
// Code to execute while the condition is true
} while someTestCondition
Switch statements are often used in place of if
statements if there is a need to test if a certain variable matches the value of another constant or variable. For example, you may want to test if an error code integer you received matches an existing constant value or if it's a new error code.
switch errorStatusCode {
case .network:
// Code to execute if it matches
case .wifi:
// Code to execute if it matches
default:
// Code to execute if nothing else matched
}
Switch statements in Swift do not fall through the bottom of each case and into the next one by default. Instead, the entire switch statement finishes its execution as soon as the first matching switch case is completed, without requiring an explicit break
statement. This makes the switch statement safer and easier to use than in C, and avoids executing more than one switch case by mistake.
Although break
is not required in Swift, you can still use a break
statement to match and ignore a particular case, or to break out of a matched case before that case has completed its execution.
return
: Stops execution and returns to the calling function. It can also be used to return a value from a function.break
: Used to stop execution of a loop.Coming soon…
Coming soon…
Coming soon…
User defaults are basically a way of storing simple preference values which can be saved and restored across app launches. It is not meant to be used as a data storage layer, like Core Data or sqlite.
let userDefaults = UserDefaults.standard
userDefaults.setValue("Some Value", forKey: "RPSomeUserPreference")
let userDefaults = UserDefaults.standard
let someValue = userDefaults.value(forKey: "RPSomeUserPreference") as AnyObject?
There are also other convenience functions on UserDefaults
instances such as bool(forKey:...)
, string(forKey:...)
, etc.
For a comprehensive list of design patterns, as established by the Gang of Four, look here: Design Patterns in Swift
Singleton's are a special kind of class where only one instance of the class exists for the current process. They are a convenient way to share data between different parts of an app without creating global variables or having to pass the data around manually, but they should be used sparingly since they often create tighter coupling between classes.
To turn a class into a singleton, you use the following implementation where the function name is prefixed with shared
plus another word which best describes your class. For example, if the class is a network or location manager, you would name the function sharedManager
instead of sharedInstance
.
class MyClass {
// MARK: - Instantiation
// Naming convention:
// sharedInstance, sharedManager, sharedController, etc.
// depending on the class type
static let sharedInstance = MyClass()
// This prevents others from using the default '()' initializer for this class.
fileprivate init() {}
var isReady = true
// More class code here
}
Explanation: The static constant sharedInstance
is run as dispatch_once
the first time that variable is accessed to make sure the initialization is atomic. This ensures it is thread safe, fast, lazy, and also bridged to ObjC for free. More from here.
Usage: You would get a reference to that singleton class in another class with the following code:
// Now you could do
let myClass = MyClass.sharedInstance
let answer = myClass.isReady ? "Yep!" : "Nope!"
print("Are you ready to rock and roll? \(answer)")
Although I don't recommend this, Swift will compile even if you use emoji's in your code since it offers Unicode support.
More info from Apple here
Author: iwasrobbed
Source Code: https://github.com/iwasrobbed/Swift-CheatSheet
1672999620
A helpful 5-page data science cheatsheet to assist with exam reviews, interview prep, and anything in-between. It covers over a semester of introductory machine learning, and is based on MIT's Machine Learning courses 6.867 and 15.072. The reader should have at least a basic understanding of statistics and linear algebra, though beginners may find this resource helpful as well.
Inspired by Maverick's Data Science Cheatsheet (hence the 2.0 in the name), located here.
Topics covered:
This cheatsheet will be occasionally updated with new/improved info, so consider a follow or star to stay up to date.
Future additions (ideas welcome):
Here are screenshots of a couple pages - the link to the full cheatsheet is above!
I planned for this resource to cover mainly algorithms, models, and concepts, as these rarely change and are common throughout industries. Technical languages and data structures often vary by job function, and refreshing these skills may make more sense on keyboard than on paper.
Author: aaronwangy
Source Code: https://github.com/aaronwangy/Data-Science-Cheatsheet
License:
1672806840
An ER diagram is a database blueprint. It facilitates data visualization and database development processes. Read on to find out what ER diagrams are and how to create them in Vertabelo.
In this article, we’ll explain what an ER diagram is and what elements it contains. We’ll discuss ER diagram abstraction levels, such as conceptual, logical, and physical diagrams. You’ll learn how to build ER diagrams using various notations, such as Crow’s Foot notation, Barker’s notation, and more. Finally, we’ll show you several examples of ER diagrams in Vertabelo.
Let’s get started.
An entity-relationship diagram (ER diagram or ERD) uses symbols to describe entities and the relationships between them. Let’s look at a simple example before jumping into definitions.
Here, the entities are Books and Authors. The attributes of the Books entity are Title, Author, Genre, and ISBN. The attributes of the Authors entity are FirstName, LastName, Email, DateOfBirth, and CountryOfOrigin.
Also, there is a many-to-many relationship between the Books and Authors entities; a book can be written by one or more authors and an author can write one or more books.
For more details, check out our earlier article on ER DIAGRAMS.
There are three main levels of abstraction that ER diagrams usually follow (although sometimes the conceptual and logical levels are combined).
The conceptual diagram is the simplest version with the highest level of abstraction. Here we identify the entities (such as people, objects, or concepts) and relationships between them. The primary consideration at this level are business rules; technical terms come later.
The next step is the logical diagram. It is built from the conceptual diagram by adding attributes to each entity and detailing the relationships (i.e. by what will become primary and foreign keys in the database). But we are still not considering a specific database platform and its technical requirements.
Here is an ARTICLE ON THE DATA TYPES AVAILABLE IN VERTABELO FOR LOGICAL MODELS.
The physical diagram is created from the logical model; it is the most precise, technical, and detailed ERD. Here we consider the target database engine and its exact data types and other features. The entities and attributes turn into tables and columns, respectively; the many-to-many relationships require additional tables to store them.
The physical model can be turned into an SQL script for database creation.
To learn more about the abstraction levels of ER diagrams, read our ARTICLE ON CONCEPTUAL, LOGICAL, AND PHYSICAL DATA MODELS.
Let’s move on to the components of ER diagrams.
Examples of entities include people, objects, or concepts. There are strong (independent) entities and weak (dependent) entities. A strong entity can exist on its own, but a weak entity is dependent on a strong entity and typically stores data associated with the strong entity. For example, a person entity is a strong entity; a person_details entity is a weak entity that extends the person entity.
Also, you may come across associative entities, which create associations between entities (i.e. storing data for a many-to-many relationship).
Here is an example of entities (without attributes) in a logical model:
In physical models, entities turn into tables that store data within a database.
Each entity contains a list of attributes. Attributes are characteristics that describe an entity. For example, a Student entity may contain the attributes StudentID, FirstName, LastName, and Email.
Here is an example of attributes in a logical model:
In physical models, attributes turn into table columns within a database:
You can learn more ABOUT THE DIFFERENCE BETWEEN ENTITIES AND ATTRIBUTES elsewhere in our blog.
ER diagrams also show the relationships between entities, but these are a bit more complex than entities and their attributes.
A relationship is a link between two entities. It defines how these entities are related to each other. Each relationship has a cardinality that indicates how many objects of one entity relate to how many objects in the other entity. Examples of cardinality include one-to-one, one-to-many, and many-to-many. Relationships between entities can also include inheritance or associations with their cardinalities.
The association relationship assigns a row from one table to a row from another table, including the cardinalities. Here, each student can be signed up for zero or more courses and each course can have zero or more students.
The inheritance relationship creates a parent-child relationship between tables. This is where attributes of a parent table are inherited by a child table (in addition to the child table’s own attributes). Here, the Student
table is a parent table to the BachelorStudent
, MasterStudent
, and PhDStudent
tables.
Physical models are similar, except that the many-to-many relationship requires an additional table to store the relationship data.
Vertabelo uses various notations to ease the process of diagram creation and enhance the readability of diagrams. All notations use symbols to represent ERD entities and relationships – e.g. boxes to represent entities and lines to represent relationships. But the details are different for each one, so let’s go through each notation.
In addition to laying out entities and defining relationships, Crow’s Foot notation allows you to define the multiplicities (or cardinalities) of the relationships between the entities.
Here are the available multiplicities:
A line connecting two entities can have either of the abovementioned multiplicities at each end.
Here are MORE ELABORATE EXAMPLES OF CROW’S FOOT NOTATION.
Here is an example of a logical ER diagram in Crow’s Foot notation:
Here is an example of a physical ER diagram in Crow’s Foot notation:
Barker’s notation defines the implementation details for entities, attributes, and relationships. Let’s look at the details of this notation scheme.
Here are MORE DETAILS ABOUT BARKER’S NOTATION.
Here is an example of a physical ER diagram in Barker’s notation:
UML is a popular modeling language used throughout the computer science world. Let’s see how it defines diagram symbols:
To learn more, visit OUR ARTICLE ON UML NOTATION.
Here is an example of a logical ER diagram in UML notation:
Here is an example of a physical ER diagram in UML notation:
The Integration DEFinition for Information Modeling (IDEF1X) notation defines entities, attributes, and relationships. Let’s discuss the details.
You can read more about the DETAILS ABOUT THE IDEF1X NOTATION SYMBOLS HERE.
Here is an example of a logical ER diagram in IDEF1X notation:
Here is an example of a physical ER diagram in IDEF1X notation:
Each notation offers a distinct yet similar way to define relationships. To learn more about it, follow our article on the THEORY AND PRACTICE OF DATABASE CARDINALITIES.
Vertabelo lets you use different notations in creating your diagrams. For conceptual or logical models, we can use Crow’s Foot, UML, or IDEF1X. And for physical models, we can use Crow’s Foot, Barker’s, UML, or IDEF1X. Here’s HOW TO CHANGE THE DIAGRAM NOTATION IN VERTABELO.
That’s all you should know before creating ER diagrams in Vertabelo.
Vertabelo lets you build conceptual, logical, and physical ER diagrams using different notations that can be changed at any time. You can choose the one that suits your requirements.
Go ahead and try it out for yourself!
Original article source at: https://www.vertabelo.com/
1666962506
This repository is complementary code for my post, UI Testing Cheat Sheet and Examples. The post goes into more detail with example images for most examples.
The included project highlights working code with a simple Test Host. This was last updated for Swift 5 on Xcode 11.4.1.
XCTAssert(app.staticTexts["Welcome"].exists)
A full text match will find an element even if the displayed text has an ellipsis due to truncation.
let longNameCell = app.staticTexts["Adolph Blaine Charles David Earl Frederick Gerald Hubert Irvin John Kenneth Lloyd Martin Nero Oliver Paul Quincy Randolph Sherman Thomas Uncas Victor William Xerxes Yancy Wolfeschlegelsteinhausenbergerdorff, Senior"]
XCTAssert(longNameCell.exists) // displayed text is "Adolph Blaine Charles David Earl Freder..."
"Waiting" is now built into XCTest.
let goLabel = app.staticTexts["Go!"]
XCTAssertFalse(goLabel.exists)
app.buttons["Ready, set..."].tap()
XCTAssert(goLabel.waitForExistence(timeout: 5))
Identify buttons by their accessibility label.
app.buttons["Add"].tap()
First make sure the text field has focus by tapping on it.
let textField = app.textFields["Username"]
textField.tap()
textField.typeText("joemasilotti")
app.alerts["Alert Title"].buttons["Button Title"].tap()
app.sheets["Sheet Title"].buttons["Button Title"].tap()
Present a location services authorization dialog to the user and dismiss it with the following code.
Before presenting the alert add a UI Interruption Handler. When this fires, dismiss with the "Allow" button.
addUIInterruptionMonitor(withDescription: "Location Services") { (alert) -> Bool in
alert.buttons["Allow"].tap()
return true
}
app.buttons["Request Location"].tap()
app.tap() // need to interact with the app again for the handler to fire
This will slide the value of the slider to 70%.
app.sliders.element.adjust(toNormalizedSliderPosition: 0.7)
A picker with one wheel:
app.pickerWheels.element.adjust(toPickerWheelValue: "Picker Wheel Item Title")
A picker with multiple wheels. Make sure to set the accessibility delegate so the framework can identify the different wheels.
let firstPredicate = NSPredicate(format: "label BEGINSWITH 'First Picker'")
let firstPicker = app.pickerWheels.element(matching: firstPredicate)
firstPicker.adjust(toPickerWheelValue: "first value")
let secondPredicate = NSPredicate(format: "label BEGINSWITH 'Second Picker'")
let secondPicker = app.pickerWheels.element(matching: secondPredicate)
secondPicker.adjust(toPickerWheelValue: "second value")
app.links["Tweet this"].tap()
XCTAssert(app.navigationBars["Details"].exists)
If you have a UITableViewCell
with default style and set the text to "Title", the reorder control's accessibility label becomes "Reorder Title".
Using this we can drag one reorder control to another, essentially reordering the cells.
let topButton = app.buttons["Reorder Top Cell"]
let bottomButton = app.buttons["Reorder Bottom Cell"]
bottomButton.press(forDuration: 0.5, thenDragTo: topButton)
XCTAssertLessThanOrEqual(bottomButton.frame.maxY, topButton.frame.minY)
Create a XCUICoordinate
from the first cell in your table and another one with a dy
of six. Then drag the first coordinate to the second.
let firstCell = app.staticTexts["Adrienne"]
let start = firstCell.coordinate(withNormalizedOffset: (CGVectorMake(0, 0))
let finish = firstCell.coordinate(withNormalizedOffset: (CGVectorMake(0, 10))
start.press(forDuration: 0, thenDragTo: finish)
Test if a view controller was pushed onto the navigation stack.
app.buttons["More Info"].tap()
XCTAssert(app.navigationBars["Volleyball?"].exists)
Pop a view controller by tapping the back button in the navigation bar and assert that the title in the navigation bar has changed.
app.navigationBars.buttons.elementBoundByIndex(0).tap()
XCTAssert(app.navigationBars["Volley"].exists)
Author: joemasilotti
Source Code: https://github.com/joemasilotti/UI-Testing-Cheat-Sheet
1665516360
Most example code taken from A Tour of Go, which is an excellent introduction to Go. If you're new to Go, do that tour. Seriously.
Basic Syntax
File hello.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello Go")
}
$ go run hello.go
Operator | Description |
---|---|
+ | addition |
- | subtraction |
* | multiplication |
/ | quotient |
% | remainder |
& | bitwise and |
| | bitwise or |
^ | bitwise xor |
&^ | bit clear (and not) |
<< | left shift |
>> | right shift |
Operator | Description |
---|---|
== | equal |
!= | not equal |
< | less than |
<= | less than or equal |
> | greater than |
>= | greater than or equal |
Operator | Description |
---|---|
&& | logical and |
|| | logical or |
! | logical not |
Operator | Description |
---|---|
& | address of / create pointer |
* | dereference pointer |
<- | send / receive operator (see 'Channels' below) |
Type goes after identifier!
var foo int // declaration without initialization
var foo int = 42 // declaration with initialization
var foo, bar int = 42, 1302 // declare and init multiple vars at once
var foo = 42 // type omitted, will be inferred
foo := 42 // shorthand, only in func bodies, omit var keyword, type is always implicit
const constant = "This is a constant"
// iota can be used for incrementing numbers, starting from 0
const (
_ = iota
a
b
c = 1 << iota
d
)
fmt.Println(a, b) // 1 2 (0 is skipped)
fmt.Println(c, d) // 8 16 (2^3, 2^4)
// a simple function
func functionName() {}
// function with parameters (again, types go after identifiers)
func functionName(param1 string, param2 int) {}
// multiple parameters of the same type
func functionName(param1, param2 int) {}
// return type declaration
func functionName() int {
return 42
}
// Can return multiple values at once
func returnMulti() (int, string) {
return 42, "foobar"
}
var x, str = returnMulti()
// Return multiple named results simply by return
func returnMulti2() (n int, s string) {
n = 42
s = "foobar"
// n and s will be returned
return
}
var x, str = returnMulti2()
func main() {
// assign a function to a name
add := func(a, b int) int {
return a + b
}
// use the name to call the function
fmt.Println(add(3, 4))
}
// Closures, lexically scoped: Functions can access values that were
// in scope when defining the function
func scope() func() int{
outer_var := 2
foo := func() int { return outer_var}
return foo
}
func another_scope() func() int{
// won't compile because outer_var and foo not defined in this scope
outer_var = 444
return foo
}
// Closures
func outer() (func() int, int) {
outer_var := 2
inner := func() int {
outer_var += 99 // outer_var from outer scope is mutated.
return outer_var
}
inner()
return inner, outer_var // return inner func and mutated outer_var 101
}
func main() {
fmt.Println(adder(1, 2, 3)) // 6
fmt.Println(adder(9, 9)) // 18
nums := []int{10, 20, 30}
fmt.Println(adder(nums...)) // 60
}
// By using ... before the type name of the last parameter you can indicate that it takes zero or more of those parameters.
// The function is invoked like any other function except we can pass as many arguments as we want.
func adder(args ...int) int {
total := 0
for _, v := range args { // Iterates over the arguments whatever the number.
total += v
}
return total
}
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32 ~= a character (Unicode code point) - very Viking
float32 float64
complex64 complex128
All Go's predeclared identifiers are defined in the builtin package.
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
// alternative syntax
i := 42
f := float64(i)
u := uint(f)
main
math/rand
=> package rand
)func main() {
// Basic one
if x > 10 {
return x
} else if x == 10 {
return 10
} else {
return -x
}
// You can put one statement before the condition
if a := b + c; a < 42 {
return a
} else {
return a - 42
}
// Type assertion inside if
var val interface{} = "foo"
if str, ok := val.(string); ok {
fmt.Println(str)
}
}
// There's only `for`, no `while`, no `until`
for i := 1; i < 10; i++ {
}
for ; i < 10; { // while - loop
}
for i < 10 { // you can omit semicolons if there is only a condition
}
for { // you can omit the condition ~ while (true)
}
// use break/continue on current loop
// use break/continue with label on outer loop
here:
for i := 0; i < 2; i++ {
for j := i + 1; j < 3; j++ {
if i == 0 {
continue here
}
fmt.Println(j)
if j == 2 {
break
}
}
}
there:
for i := 0; i < 2; i++ {
for j := i + 1; j < 3; j++ {
if j == 1 {
continue
}
fmt.Println(j)
if j == 2 {
break there
}
}
}
// switch statement
switch operatingSystem {
case "darwin":
fmt.Println("Mac OS Hipster")
// cases break automatically, no fallthrough by default
case "linux":
fmt.Println("Linux Geek")
default:
// Windows, BSD, ...
fmt.Println("Other")
}
// as with for and if, you can have an assignment statement before the switch value
switch os := runtime.GOOS; os {
case "darwin": ...
}
// you can also make comparisons in switch cases
number := 42
switch {
case number < 42:
fmt.Println("Smaller")
case number == 42:
fmt.Println("Equal")
case number > 42:
fmt.Println("Greater")
}
// cases can be presented in comma-separated lists
var char byte = '?'
switch char {
case ' ', '?', '&', '=', '#', '+', '%':
fmt.Println("Should escape")
}
var a [10]int // declare an int array with length 10. Array length is part of the type!
a[3] = 42 // set elements
i := a[3] // read elements
// declare and initialize
var a = [2]int{1, 2}
a := [2]int{1, 2} //shorthand
a := [...]int{1, 2} // elipsis -> Compiler figures out array length
var a []int // declare a slice - similar to an array, but length is unspecified
var a = []int {1, 2, 3, 4} // declare and initialize a slice (backed by the array given implicitly)
a := []int{1, 2, 3, 4} // shorthand
chars := []string{0:"a", 2:"c", 1: "b"} // ["a", "b", "c"]
var b = a[lo:hi] // creates a slice (view of the array) from index lo to hi-1
var b = a[1:4] // slice from index 1 to 3
var b = a[:3] // missing low index implies 0
var b = a[3:] // missing high index implies len(a)
a = append(a,17,3) // append items to slice a
c := append(a,b...) // concatenate slices a and b
// create a slice with make
a = make([]byte, 5, 5) // first arg length, second capacity
a = make([]byte, 5) // capacity is optional
// create a slice from an array
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x
len(a)
gives you the length of an array/a slice. It's a built-in function, not a attribute/method on the array.
// loop over an array/a slice
for i, e := range a {
// i is the index, e the element
}
// if you only need e:
for _, e := range a {
// e is the element
}
// ...and if you only need the index
for i := range a {
}
// In Go pre-1.4, you'll get a compiler error if you're not using i and e.
// Go 1.4 introduced a variable-free form, so that you can do this
for range time.Tick(time.Second) {
// do it once a sec
}
m := make(map[string]int)
m["key"] = 42
fmt.Println(m["key"])
delete(m, "key")
elem, ok := m["key"] // test if key "key" is present and retrieve it, if so
// map literal
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
// iterate over map content
for key, value := range m {
}
There are no classes, only structs. Structs can have methods.
// A struct is a type. It's also a collection of fields
// Declaration
type Vertex struct {
X, Y float64
}
// Creating
var v = Vertex{1, 2}
var v = Vertex{X: 1, Y: 2} // Creates a struct by defining values with keys
var v = []Vertex{{1,2},{5,2},{5,5}} // Initialize a slice of structs
// Accessing members
v.X = 4
// You can declare methods on structs. The struct you want to declare the
// method on (the receiving type) comes between the the func keyword and
// the method name. The struct is copied on each method call(!)
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
// Call method
v.Abs()
// For mutating methods, you need to use a pointer (see below) to the Struct
// as the type. With this, the struct value is not copied for the method call.
func (v *Vertex) add(n float64) {
v.X += n
v.Y += n
}
Anonymous structs: Cheaper and safer than using map[string]interface{}
.
point := struct {
X, Y int
}{1, 2}
p := Vertex{1, 2} // p is a Vertex
q := &p // q is a pointer to a Vertex
r := &Vertex{1, 2} // r is also a pointer to a Vertex
// The type of a pointer to a Vertex is *Vertex
var s *Vertex = new(Vertex) // new creates a pointer to a new struct instance
// interface declaration
type Awesomizer interface {
Awesomize() string
}
// types do *not* declare to implement interfaces
type Foo struct {}
// instead, types implicitly satisfy an interface if they implement all required methods
func (foo Foo) Awesomize() string {
return "Awesome!"
}
There is no subclassing in Go. Instead, there is interface and struct embedding.
// ReadWriter implementations must satisfy both Reader and Writer
type ReadWriter interface {
Reader
Writer
}
// Server exposes all the methods that Logger has
type Server struct {
Host string
Port int
*log.Logger
}
// initialize the embedded type the usual way
server := &Server{"localhost", 80, log.New(...)}
// methods implemented on the embedded struct are passed through
server.Log(...) // calls server.Logger.Log(...)
// the field name of the embedded type is its type name (in this case Logger)
var logger *log.Logger = server.Logger
There is no exception handling. Instead, functions that might produce an error just declare an additional return value of type error
. This is the error
interface:
// The error built-in interface type is the conventional interface for representing an error condition,
// with the nil value representing no error.
type error interface {
Error() string
}
Here's an example:
func sqrt(x float64) (float64, error) {
if x < 0 {
return 0, errors.New("negative value")
}
return math.Sqrt(x), nil
}
func main() {
val, err := sqrt(-1)
if err != nil {
// handle error
fmt.Println(err) // negative value
return
}
// All is good, use `val`.
fmt.Println(val)
}
Concurrency
Goroutines are lightweight threads (managed by Go, not OS threads). go f(a, b)
starts a new goroutine which runs f
(given f
is a function).
// just a function (which can be later started as a goroutine)
func doStuff(s string) {
}
func main() {
// using a named function in a goroutine
go doStuff("foobar")
// using an anonymous inner function in a goroutine
go func (x int) {
// function body goes here
}(42)
}
ch := make(chan int) // create a channel of type int
ch <- 42 // Send a value to the channel ch.
v := <-ch // Receive a value from ch
// Non-buffered channels block. Read blocks when no value is available, write blocks until there is a read.
// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch := make(chan int, 100)
close(ch) // closes the channel (only sender should close)
// read from channel and test if it has been closed
v, ok := <-ch
// if ok is false, channel has been closed
// Read from channel until it is closed
for i := range ch {
fmt.Println(i)
}
// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
func doStuff(channelOut, channelIn chan int) {
select {
case channelOut <- 42:
fmt.Println("We could write to channelOut!")
case x := <- channelIn:
fmt.Println("We could read from channelIn")
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}
A send to a nil channel blocks forever
var c chan string
c <- "Hello, World!"
// fatal error: all goroutines are asleep - deadlock!
A receive from a nil channel blocks forever
var c chan string
fmt.Println(<-c)
// fatal error: all goroutines are asleep - deadlock!
A send to a closed channel panics
var c = make(chan string, 1)
c <- "Hello, World!"
close(c)
c <- "Hello, Panic!"
// panic: send on closed channel
A receive from a closed channel returns the zero value immediately
var c = make(chan int, 2)
c <- 1
c <- 2
close(c)
for i := 0; i < 3; i++ {
fmt.Printf("%d ", <-c)
}
// 1 2 0
fmt.Println("Hello, 你好, नमस्ते, Привет, ᎣᏏᏲ") // basic print, plus newline
p := struct { X, Y int }{ 17, 2 }
fmt.Println( "My point:", p, "x coord=", p.X ) // print structs, ints, etc
s := fmt.Sprintln( "My point:", p, "x coord=", p.X ) // print to string variable
fmt.Printf("%d hex:%x bin:%b fp:%f sci:%e",17,17,17,17.0,17.0) // c-ish format
s2 := fmt.Sprintf( "%d %f", 17, 17.0 ) // formatted print to string variable
hellomsg := `
"Hello" in Chinese is 你好 ('Ni Hao')
"Hello" in Hindi is नमस्ते ('Namaste')
` // multi-line string literal, using back-tick at beginning and end
A type switch is like a regular switch statement, but the cases in a type switch specify types (not values) which are compared against the type of the value held by the given interface value.
func do(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v bytes long\n", v, len(v))
default:
fmt.Printf("I don't know about type %T!\n", v)
}
}
func main() {
do(21)
do("hello")
do(true)
}
Snippets
Go programs can embed static files using the "embed"
package as follows:
package main
import (
"embed"
"log"
"net/http"
)
// content holds the static content (2 files) for the web server.
//go:embed a.txt b.txt
var content embed.FS
func main() {
http.Handle("/", http.FileServer(http.FS(content)))
log.Fatal(http.ListenAndServe(":8080", nil))
}
package main
import (
"fmt"
"net/http"
)
// define a type for the response
type Hello struct{}
// let that type implement the ServeHTTP method (defined in interface http.Handler)
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello!")
}
func main() {
var h Hello
http.ListenAndServe("localhost:4000", h)
}
// Here's the method signature of http.ServeHTTP:
// type Handler interface {
// ServeHTTP(w http.ResponseWriter, r *http.Request)
// }
Author: a8m
Source Code: https://github.com/a8m/golang-cheat-sheet