반응형
반응형

Python의 matplotlib 라이브러리를 사용하여 polar plot(극좌표 플롯)을 쉽게 그릴 수 있습니다. polar plot은 데이터를 각도와 반경을 사용하여 나타내며, 방위 데이터나 주기적인 패턴을 표현하는 데 유용합니다.

* 코드 설명
    1.theta와 r 설정: theta는 각도 값, r은 반경 값입니다.
         1.1.theta는 0에서 2π까지 균일하게 분포된 100개의 값을 가지며, np.linspace를 사용하여 생성합니다.
         1.2.r은 sin(3 * theta) 함수를 이용하여 생성된 반경 값에 1을 더하여 그래프를 그립니다.

                 이 함수는 각도에 따른 반경의 변화를 표현하며, 주기적인 패턴을 생성합니다.
     2.polar=True 옵션: plt.subplot(111, polar=True)로 설정하여 polar plot을 생성합니다.
     3.그래프 출력: plt.show()로 결과를 화면에 출력합니다.

import matplotlib.pyplot as plt
import numpy as np

# 각도 (theta)와 반경 (r) 값 생성
theta = np.linspace(0, 2 * np.pi, 100)  # 0에서 2π 사이의 각도 값
r = 1 + np.sin(3 * theta)               # 반경 값은 특정 함수로 정의

# Polar plot 생성
plt.figure(figsize=(6, 6))
ax = plt.subplot(111, polar=True)       # polar=True 옵션으로 polar plot 생성
ax.plot(theta, r)

# 플롯 설정
ax.set_title("Polar Plot Example", va='bottom')
plt.show()

import matplotlib.pyplot as plt
import numpy as np

# 임의의 데이터
theta = np.array([0, np.pi/4, np.pi/2, 3*np.pi/4, np.pi])  # 각도 데이터
r = np.array([1, 2, 3, 4, 5])                              # 반경 데이터

# Polar plot 생성
plt.figure(figsize=(6, 6))
ax = plt.subplot(111, polar=True)
ax.plot(theta, r, marker='o')

# 플롯 설정
ax.set_title("Custom Data Polar Plot", va='bottom')
plt.show()

반응형
반응형

커피챗은 무슨 뜻인가요? 커피챗(Coffee Chat)은 서구권에서는 이미 일상이 된 정보형 미팅으로 '궁금한 업계/회사/직무/학교'의 사람과 실제 만남을 통해 커피 한 잔 마시며 부담 없이 정보를 묻고 답하는 문화입니다.

반응형
반응형

https://www.cio.com/article/3575332/%eb%b8%94%eb%a1%9c%ea%b7%b8-%ec%8b%a0%eb%a2%b0%ec%9d%98-%ec%9c%84%ea%b8%b0%ec%9d%bc%ea%b9%8c%c2%b7%c2%b7%c2%b7-it-%eb%b6%80%ec%84%9c%ec%9d%98-%eb%b6%80%eb%8b%b4%ec%9d%84-%ec%a4%84.html

 

블로그 | ‘신뢰의 위기’일까?··· IT 부서의 부담을 줄여야 할 때

IT 부서는 AI의 급부상으로 인해 압박을 받고 있다. 최고 경영진의 신뢰마저 감소하고 있다. 하지만 이런 어려움은 일시적일 수 있다. 비즈니스와 IT의 연계가 양방향으로 이뤄져야 한다는 의미일

www.cio.com

IT 부서는 AI의 급부상으로 인해 압박을 받고 있다. 최고 경영진의 신뢰마저 감소하고 있다. 하지만 이런 어려움은 일시적일 수 있다. 비즈니스와 IT의 연계가 양방향으로 이뤄져야 한다는 의미일 수도 있다.

 
 

지난 9월 가트너는 CIO가 당면한 주요 과제 목록을 발표했다. AI, 새로운 보안 과제, 인재 격차 등 현재 IT의 문제도 언급됐지만, 설문조사에 참여한 1만 2,000명의 CIO들이 언급한 주요 고충은 IT 투자에 비즈니스 가치가 있다는 것을 경영진에게 입증해야 한다는 보다 전통적인 과제였다.

최근에는 IT 부서에 대한 기업 경영진의 신뢰가 지난 10년간 감소했다는 IBM의 연구 결과를 인용한 보고서가 발표됐다. 설문에 참여한 CEO 중 36%만이 IT 부서가 기본 서비스를 제공할 수 있다고 확신했는데, 이는 2013년의 64%에 비해 크게 감소한 수치다.

‘신뢰의 위기’가 왔다는 뜻일까? 경영진이 새로운 IT 투자의 가치를 납득해야 하고, 동시에 IT 부서가 가장 기본적인 업무조차 처리할 수 없다고 믿는다면 그렇게 보일 수 있다. 하지만 잘 모르겠다.

 

가트너, IBM 및 기타 전문가들의 조언을 살펴보면 익숙한 내용이 많다. IT와 비즈니스는 함께 가야 한다, IT 리더는 기업 경영진과 비즈니스 언어로 소통해야 한다, IT 리더는 시스템 가동과 혁신 사이에서 균형을 찾아야 한다 등 필자가 이 문제를 접해 온 약 20년 동안 강조됐던 내용이다. 그 조언이 새로운 내용이 아니라는 점에서, 문제 자체도 새롭지 않다고 생각한다.

외부 관찰자로서 보자면 어떤 면에서는 지루하기도 하다. 어떻게 여전히 ‘IT와 비즈니스가 서로 대화해야 하는 것’이 문제가 될 수 있을까? 기업에서 IT는 여전히 특별한 관심 영역이나 필요악으로 여겨지는 걸까? 기업 가치 최상단에 있는 대부분이 IT 기업이고, IT가 대륙 전체의 경쟁력을 결정짓는 요소로 꼽히는 세상에서?

안타깝게도 부분적으로는 그렇다고 생각한다. 하지만 동시에 외부 상황이 기업과 IT 부서를 어떤 시험에 들게 하는가에 따라 이런 문제가 주기적으로 반복된다고 본다. 예를 들어 팬데믹 때를 언급할 수 있다. CIO와 IT 부서는 기업이 빠르게 적응할 수 있도록 도왔다는 점에서 영웅으로 칭송받았다. 이는 물론 도구, 기능, 프로세스, 지원과 같은 ‘전통적인’ IT 업무에 관한 것이었다. 잘 작동하는 IT 조직은 이런 과제에서 탁월한 성과를 낼 수 있었다.

 

하지만 지금은 팬데믹이 아니라 AI 열풍에 대응해야 하는 시기다. 이제 기업 경영진은 AI 개발에 뒤처지지 않기를 요구한다. 혁신과 시스템 가동 시간 사이의 딜레마가 다시 부각되고 있는 것이다. 특히 IT 부서가 2가지를 모두 처리해야 하는 많은 기업에서 문제가 되고 있다. 균형을 찾는 일은 평상시에도 어렵지만, 완전히 새로운 역량을 요구하는 기술 분야가 등장해 다른 모든 업무를 보류시킨 지금과 같은 상황에선 더욱 어렵다. ‘불을 계속 켜두는’ 동시에 아예 새로운 광원을 발명하는 일이 어려운 것은 당연하다.

물론 기술 개발이 너무 빨라 프로세스를 변경하거나 기술을 습득할 시간이 없기 때문에 CIO와 IT 부서가 압박을 받는다는 데에는 의심의 여지가 없다. 하지만 이는 일시적인 문제일 수 있다. 비즈니스 리더가 눈앞에 반짝이는 인공지능이 아니라 시간이 지남에 따라 IT의 가치를 실제로 인식할 수 있다면 말이다.

솔직히 말해, 20년 동안 IT가 비즈니스를 이해하고 경영진이 이해할 수 있는 언어로 소통해야 한다는 말을 들어왔다. 이제 기업 경영진이 IT와 소통하는 법을 배워야 할 때가 되지 않았을까?

반응형
반응형

SQL Server에서 A, B, 그리고 각각의 A 값에 대한 카운트를 하나의 행에 열로 표시하려면, 피벗(PIVOT) 기능을 사용할 수 있습니다. 피벗을 사용하면 각 A 값이 열로 변환되며, 각 열의 값은 해당 A 값의 카운트가 됩니다.

가정: 테이블 구조

  • TableName 테이블에 A, B 열이 있다고 가정합니다.
  • A 열에는 여러 종류의 값이 있으며, 이 값들을 기준으로 카운트를 집계합니다.

예제: 피벗을 사용하여 A 값의 카운트를 열로 표시

SELECT 
    B,
    [A1],
    [A2],
    [A3],
    [A4],
    [A5]
FROM (
    SELECT 
        B,
        A,
        COUNT(1) AS CountA
    FROM 
        TableName
    GROUP BY 
        B, A
) AS SourceTable
PIVOT (
    SUM(CountA)
    FOR A IN ([A1], [A2], [A3], [A4], [A5])
) AS PivotTable
ORDER BY B;​

설명:

  1. 서브쿼리: 먼저 B, A, 그리고 각 A 값의 카운트를 집계합니다.
    • GROUP BY B, A: B와 A로 그룹화하여 각 A 값에 대한 카운트를 계산합니다.
  2. 피벗:
    • PIVOT (SUM(CountA) FOR A IN ([A1], [A2], [A3], [A4], [A5])): 각 A 값이 열로 변환되며, 각 열의 값은 해당 A의 카운트입니다.
  3. 결과: 최종적으로 B와 각 A 값의 카운트를 열로 표시합니다.

주의사항:

  • IN 절에 지정된 A1, A2, A3, A4, A5는 실제로 A 컬럼에 있는 값으로 대체해야 합니다. 예를 들어, A 값이 'Type1', 'Type2', 'Type3' 등일 경우, 해당 값을 정확하게 열 이름으로 지정해야 합니다.
  • 만약 A 값의 종류가 동적으로 변화한다면, 동적 SQL을 사용하여 피벗 쿼리를 작성해야 할 수 있습니다.

동적 피벗 예시

동적 피벗을 사용하면 테이블의 A 값이 변해도 자동으로 피벗을 적용할 수 있습니다.

DECLARE @cols AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX);

-- A 값 가져오기
SELECT @cols = STRING_AGG(QUOTENAME(A), ', ')
FROM (SELECT DISTINCT A FROM TableName) AS Temp;

-- 피벗 쿼리 생성
SET @query = 'SELECT B, ' + @cols + '
              FROM (
                  SELECT B, A, COUNT(1) AS CountA
                  FROM TableName
                  GROUP BY B, A
              ) AS SourceTable
              PIVOT (
                  SUM(CountA)
                  FOR A IN (' + @cols + ')
              ) AS PivotTable
              ORDER BY B;';

-- 실행
EXEC sp_executesql @query;​

이 동적 피벗 예시는 A 값의 종류에 따라 자동으로 피벗 쿼리를 생성하고 실행합니다.

반응형
반응형

[python] 난수 10자리에서 영문 숫자 분포가 골고루 들어갈수있게

 

import random
import string

def generate_balanced_random_string(length=10):
    # 원하는 비율로 대문자, 소문자, 숫자 개수 설정
    num_uppercase = 4  # 대문자 4개
    num_lowercase = 3  # 소문자 3개
    num_digits = 3     # 숫자 3개

    # 각 문자 유형에서 원하는 만큼 선택
    uppercase_letters = random.choices(string.ascii_uppercase, k=num_uppercase)
    lowercase_letters = random.choices(string.ascii_lowercase, k=num_lowercase)
    digits = random.choices(string.digits, k=num_digits)

    # 모든 문자들을 합쳐서 무작위로 섞음
    random_string = uppercase_letters + lowercase_letters + digits
    random.shuffle(random_string)

    # 리스트를 문자열로 변환하여 반환
    return ''.join(random_string)

# 함수 호출
random_string = generate_balanced_random_string()
print(f"균형 잡힌 10자리 난수: {random_string}")
반응형
반응형

JavaScript is a versatile and powerful language that is essential for modern web development. Here are super hacks that will make you a more efficient and effective JavaScript developer, with detailed explanations and examples for each one.

1. Use `let` and `const` Instead of `var`

Problem: `var` has function scope which can lead to bugs and unpredictable behavior.

Solution: Use `let` and `const` which have block scope.

let count = 0;
const PI = 3.14;

Using `let` and `const` helps prevent scope-related bugs by ensuring variables are only accessible within the block they are defined.

2. Default Parameters

Problem: Functions can fail if arguments are not provided.

Solution: Use default parameters to set fallback values.

function greet(name = 'Guest') {
return `Hello, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"

Default parameters ensure that a function has sensible defaults, preventing errors and making the code more robust.

3. Template Literals

Problem: String concatenation can be cumbersome and error-prone.

Solution: Use template literals for cleaner and more readable string interpolation.

const name = 'John';
const greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, John!"

Template literals make it easier to create strings with embedded expressions and multi-line strings.

4. Destructuring Assignment

Problem: Extracting values from objects and arrays can be verbose.

Solution: Use destructuring assignment to extract values more succinctly.

const user = { name: 'Jane', age: 25 };
const { name, age } = user;
console.log(name, age); // "Jane" 25

Destructuring assignment allows you to extract properties from objects and elements from arrays into distinct variables easily.

5. Arrow Functions

Problem: Traditional function expressions can be verbose and don’t bind `this` lexically.

Solution: Use arrow functions for shorter syntax and lexical `this`.

const add = (a, b) => a + b;
console.log(add(2, 3)); // 5

Arrow functions provide a concise syntax for function expressions and ensure that `this` is lexically bound.

6. Spread Operator

Problem: Combining arrays or objects can be cumbersome.

Solution: Use the spread operator to easily combine arrays and objects.

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = […arr1, …arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

The spread operator allows you to spread the elements of an array or object into another array or object.

7. Rest Parameters

Problem: Handling a variable number of function arguments can be tricky.

Solution: Use rest parameters to capture all arguments in an array.

function sum(…args) {
return args.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

Rest parameters allow you to handle an indefinite number of arguments as an array, making your functions more flexible.

8. Short-Circuit Evaluation

Problem: Writing conditional statements can be verbose.

Solution: Use short-circuit evaluation to write concise conditions.

const isLoggedIn = true;
const user = isLoggedIn && { name: 'Jane', age: 25 };
console.log(user); // { name: 'Jane', age: 25 }

Short-circuit evaluation uses the logical `&&` and `||` operators to simplify conditional expressions.

9. Optional Chaining

Problem: Accessing deeply nested properties can lead to errors if any part of the chain is `null` or `undefined`.

Solution: Use optional chaining to safely access nested properties.

const user = { profile: { name: 'Jane' } };
const userName = user?.profile?.name;
console.log(userName); // "Jane"

Optional chaining allows you to safely access nested properties without having to explicitly check each level of the chain for `null` or `undefined`.

10. Nullish Coalescing

Problem: Using `||` to provide default values can give unexpected results if the value is `0` or `””`.

Solution: Use nullish coalescing (`??`) to provide default values only when `null` or `undefined`.

const user = { name: '', age: 0 };
const userName = user.name ?? 'Anonymous';
const userAge = user.age ?? 18;
console.log(userName); // ""
console.log(userAge); // 0

Nullish coalescing allows you to provide default values only when the left-hand side is `null` or `undefined`.

11. Object Property Shorthand

Problem: Assigning variables to object properties can be repetitive.

Solution: Use property shorthand to simplify object creation.

const name = 'Jane';
const age = 25;
const user = { name, age };
console.log(user); // { name: 'Jane', age: 25 }

Property shorthand allows you to omit the property name when it matches the variable name, making the code cleaner.

12. Dynamic Property Names

Problem: Creating objects with dynamic property names can be verbose.

Solution: Use computed property names to dynamically create object properties.

const propName = 'age';
const user = { name: 'Jane', [propName]: 25 };
console.log(user); // { name: 'Jane', age: 25 }

Computed property names allow you to create object properties dynamically, using the value of an expression as the property name.

13. Array `map()`, `filter()`, and `reduce()`

Problem: Iterating over arrays to transform, filter, or accumulate values can be repetitive.

Solution: Use `map()`, `filter()`, and `reduce()` for common array operations.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15

These array methods provide a functional approach to transforming, filtering, and reducing arrays, making your code more expressive and concise.

14. String `includes()`, `startsWith()`, and `endsWith()`

Problem: Checking if a string contains, starts with, or ends with a substring can be verbose.

Solution: Use `includes()`, `startsWith()`, and `endsWith()` for simpler string checks.

const str = 'Hello, world!';
console.log(str.includes('world')); // true
console.log(str.startsWith('Hello')); // true
console.log(str.endsWith('!')); // true

These string methods provide a simple and readable way to check for the presence, start, or end of a substring.

15. Array and Object Destructuring in Function Parameters

Problem: Extracting values from arrays or objects passed as function parameters can be verbose.

Solution: Use destructuring in function parameters to directly extract values.

const user = { name: 'Jane', age: 25 };
function greet({ name, age }) {
return `Hello, ${name}! You are ${age} years old.`;
}
console.log(greet(user)); // "Hello, Jane! You are 25 years old."

Destructuring in function parameters allows you to directly extract values from objects or arrays passed to the function, making the code more concise and readable.

16. Default Values in Destructuring

Problem: Handling missing properties when destructuring objects can be cumbersome.

Solution: Use default values in destructuring to provide fallback values.

const user = { name: 'Jane' };
const { name, age = 18 } = user;
console.log(name); // "Jane"
console.log(age); // 18

Default values in destructuring allow you to provide fallback values for properties that may be missing, making your code more robust.

17. Object `assign()`

Problem: Cloning or merging objects can be verbose and error-prone.

Solution: Use `Object.assign()` to clone or merge objects.

const target = { a: 1 };
const source = { b: 2 };
const merged = Object.assign(target, source);
console.log(merged); // { a: 1, b: 2 }

`Object.assign()` allows you to clone or merge objects efficiently, reducing the need for manual copying.

18. Array `find()` and `findIndex()`

Problem: Finding an element or its index in an array can be cumbersome

with loops.

Solution: Use `find()` and `findIndex()` for more readable code.

const users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
const user = users.find(u => u.id === 1);
console.log(user); // { id: 1, name: 'Jane' }
const index = users.findIndex(u => u.id === 1);
console.log(index); // 0

These array methods provide a simple way to find an element or its index based on a condition, improving code readability.

19. Array `some()` and `every()`

Problem: Checking if some or all elements in an array meet a condition can be verbose.

Solution: Use `some()` and `every()` for cleaner code.

const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // false

These array methods allow you to check if some or all elements in an array meet a condition in a concise way.

20. Array `flat()` and `flatMap()`

Problem: Flattening nested arrays or mapping and flattening arrays can be cumbersome.

Solution: Use `flat()` and `flatMap()` for more readable code.

const nested = [1, [2, [3, [4]]]];
const flat = nested.flat(2);
console.log(flat); // [1, 2, 3, [4]]
const mapped = [1, 2, 3].flatMap(x => [x, x * 2]);
console.log(mapped); // [1, 2, 2, 4, 3, 6]

These array methods provide a simple way to flatten nested arrays and to map and flatten in a single step.

21. Array `from()` and `of()`

Problem: Creating arrays from iterable objects or arguments can be verbose.

Solution: Use `Array.from()` and `Array.of()` for cleaner code.

const set = new Set([1, 2, 3]);
const arrFromSet = Array.from(set);
console.log(arrFromSet); // [1, 2, 3]
const arrOfNumbers = Array.of(1, 2, 3);
console.log(arrOfNumbers); // [1, 2, 3]

`Array.from()` allows you to create arrays from iterable objects, and `Array.of()` allows you to create arrays from a list of arguments.

22. Parameter Destructuring in Callbacks

Problem: Accessing properties of objects passed to callbacks can be verbose.

Solution: Use destructuring in callback parameters for cleaner code.

const users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
users.forEach(({ id, name }) => {
console.log(`User ID: ${id}, User Name: ${name}`);
});

Destructuring in callback parameters allows you to directly access properties of objects passed to the callback, making the code more concise.

23. Optional Callback Functions

Problem: Handling optional callback functions can be cumbersome.

Solution: Use short-circuit evaluation to call optional callbacks.

function fetchData(url, callback) {
fetch(url)
.then(response => response.json())
.then(data => {
callback && callback(data);
});
}

Short-circuit evaluation allows you to call an optional callback function only if it is provided, making the code more robust.

24. Promisify Callbacks

Problem: Converting callback-based functions to promises can be cumbersome.

Solution: Use a utility function to promisify callbacks.

function promisify(fn) {
return function (…args) {
return new Promise((resolve, reject) => {
fn(…args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}
const readFile = promisify(require('fs').readFile);
readFile('path/to/file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));

Promisifying allows you to convert callback-based functions to promises, making it easier to work with async/await syntax.

25. Async/Await for Synchronous-Like Code

Problem: Writing asynchronous code with promises can be verbose and hard to read.

Solution: Use async/await to write asynchronous code in a synchronous style.

async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData('https://api.example.com/data');

Async/await provides a way to write asynchronous code that looks and behaves like synchronous code, improving readability and maintainability.

26. Chaining Promises

Problem: Handling multiple asynchronous operations sequentially can be cumbersome.

Solution: Chain promises to handle multiple asynchronous operations.

fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('Data:', data);
return fetch('https://api.example.com/more-data');
})
.then(response => response.json())
.then(moreData => {
console.log('More Data:', moreData);
})
.catch(error => {
console.error('Error:', error);
});

Chaining promises allows you to handle multiple asynchronous operations sequentially, improving readability and maintainability.

27. Promise.all for Concurrent Execution

Problem: Handling multiple asynchronous operations concurrently can be challenging.

Solution: Use `Promise.all` to handle concurrent asynchronous operations.

const fetchData1 = fetch('https://api.example.com/data1').then(response => response.json());
const fetchData2 = fetch('https://api.example.com/data2').then(response => response.json());
Promise.all([fetchData1, fetchData2])
.then(([data1, data2]) => {
console.log('Data 1:', data1);
console.log('Data 2:', data2);
})
.catch(error => {
console.error('Error:', error);
});

`Promise.all` allows you to handle multiple asynchronous operations concurrently and proceed when all of them are completed.

28. Debounce Function

Problem: Frequent function calls, such as during a window resize event, can degrade performance.

Solution: Use a debounce function to limit the rate at which a function is executed.

function debounce(func, wait) {
let timeout;
return function (…args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
window.addEventListener('resize', debounce(() => {
console.log('Window resized');
}, 200));

A debounce function ensures that a function is only called after a certain period of inactivity, improving performance.

29. Throttle Function

Problem: Limiting the rate of function execution for events that fire frequently, like scroll or resize.

Solution: Use a throttle function to limit the execution rate of a function.

function throttle(func, limit) {
let lastFunc;
let lastRan;
return function (…args) {
if (!lastRan) {
func.apply(this, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func.apply(this, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
window.addEventListener('scroll', throttle(() => {
console.log('Window scrolled');
}, 200));

A throttle function ensures that a function is only called at most once in a specified period, improving performance for frequently firing events.

30. Deep Clone Objects

Problem: Cloning nested objects can be tricky and error-prone.

Solution: Use structured cloning or libraries like Lodash to deep clone objects.

const obj = { a: 1, b: { c: 2 } };
const deepClone = JSON.parse(JSON.stringify(obj));
console.log(deepClone); // { a: 1, b: { c: 2 } }

Deep cloning ensures that nested objects are copied by value, not by reference, preventing unintended modifications to the original object.

31. Memoization

Problem: Repeatedly calling expensive functions can degrade performance.

Solution: Use memoization to cache results of expensive function calls.

function memoize(func) {
const cache = new Map();
return function (…args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(this, args);
cache.set(key, result);
return result;
};
}
const expensiveFunction = memoize((num) => {
console.log('Computing…');
return num * 2;
});
console.log(expensiveFunction(2)); // "Comput
ing…" 4
console.log(expensiveFunction(2)); // 4

Memoization improves performance by caching results of expensive function calls and returning the cached result for subsequent calls with the same arguments.

32. Currying Functions

Problem: Creating functions with multiple parameters can be cumbersome.

Solution: Use currying to create functions with partially applied parameters.

function curry(func) {
return function curried(…args) {
if (args.length >= func.length) {
return func.apply(this, args);
}
return function (…nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6

Currying allows you to create functions that can be called with fewer arguments, returning a new function that accepts the remaining arguments.

33. Partial Application

Problem: Calling functions with repetitive arguments can be tedious.

Solution: Use partial application to pre-apply some arguments to a function.

function partial(func, …presetArgs) {
return function (…laterArgs) {
return func(…presetArgs, …laterArgs);
};
}
const multiply = (a, b, c) => a * b * c;
const double = partial(multiply, 2);
console.log(double(3, 4)); // 24

Partial application allows you to create new functions by pre-applying some arguments, making your code more flexible and reusable.

34. Function Composition

Problem: Combining multiple functions into a single operation can be cumbersome.

Solution: Use function composition to combine multiple functions.

const compose = (…funcs) => (arg) =>
funcs.reduceRight((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = compose(multiply, add);
console.log(addThenMultiply(5)); // 12

Function composition allows you to create a new function by combining multiple functions, making your code more modular and reusable.

35. Function Pipelining

Problem: Applying a series of functions to a value can be verbose.

Solution: Use function pipelining to apply a series of functions in sequence.

const pipe = (…funcs) => (arg) =>
funcs.reduce((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = pipe(add, multiply);
console.log(addThenMultiply(5)); // 12

Function pipelining allows you to apply a series of functions to a value in sequence, improving code readability and maintainability.

36. Self-Invoking Functions

Problem: Executing a function immediately upon definition can be cumbersome.

Solution: Use an Immediately Invoked Function Expression (IIFE).

(function () {
console.log('This runs immediately!');
})();

IIFEs allow you to execute a function immediately upon definition, useful for creating isolated scopes and avoiding polluting the global namespace.

37. Avoid Global Variables

Problem: Global variables can lead to conflicts and unintended side effects.

Solution: Use local variables and modules to avoid polluting the global namespace.

// Using local variables
function doSomething() {
let localVariable = 'This is local';
console.log(localVariable);
}
// Using modules
const myModule = (function () {
let privateVariable = 'This is private';
return {
publicMethod() {
console.log(privateVariable);
},
};
})();
myModule.publicMethod(); // "This is private"

Avoiding global variables helps prevent conflicts and unintended side effects, making your code more modular and maintainable.

38. Encapsulation with Closures

Problem: Exposing internal details of a function can lead to misuse.

Solution: Use closures to encapsulate internal details.

function createCounter() {
let count = 0;
return {
increment() {
count++;
return count;
},
decrement() {
count - ;
return count;
},
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1

Closures allow you to encapsulate internal details and expose only the necessary functionality, improving code security and maintainability.

39. Module Pattern

Problem: Organizing code into reusable modules can be challenging.

Solution: Use the module pattern to create reusable and encapsulated code.

const myModule = (function () {
let privateVariable = 'This is private';
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod() {
privateMethod();
},
};
})();
myModule.publicMethod(); // "This is private"

The module pattern allows you to create reusable and encapsulated code, improving code organization and maintainability.

40. Singleton Pattern

Problem: Ensuring only one instance of a class is created can be challenging.

Solution: Use the singleton pattern to create a single instance.

const singleton = (function () {
let instance;
function createInstance() {
return {
name: 'Singleton Instance',
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // true

The singleton pattern ensures that only one instance of a class is created, useful for managing shared resources or configurations.

41. Factory Pattern

Problem: Creating objects with complex initialization can be cumbersome.

Solution: Use the factory pattern to create objects.

function createUser(name, role) {
return {
name,
role,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am a ${this.role}`);
},
};
}
const admin = createUser('Alice', 'admin');
const user = createUser('Bob', 'user');
admin.sayHello(); // "Hello, my name is Alice and I am an admin"
user.sayHello(); // "Hello, my name is Bob and I am a user"

The factory pattern allows you to create objects with complex initialization in a flexible and reusable way.

42. Observer Pattern

Problem: Managing state changes and notifying multiple components can be challenging.

Solution: Use the observer pattern to manage state changes and notify observers.

function Subject() {
this.observers = [];
}
Subject.prototype = {
subscribe(observer) {
this.observers.push(observer);
},
unsubscribe(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
},
notify(data) {
this.observers.forEach((observer) => observer.update(data));
},
};
function Observer(name) {
this.name = name;
}
Observer.prototype.update = function (data) {
console.log(`${this.name} received data: ${data}`);
};
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('New data available'); // "Observer 1 received data: New data available" "Observer 2 received data: New data available"

The observer pattern allows you to manage state changes and notify multiple observers, improving code organization and maintainability.

43. Event Delegation

Problem: Adding event listeners to multiple elements can degrade performance.

Solution: Use event delegation to manage events efficiently.

document.getElementById('parent').addEventListener('click', (event) => {
if (event.target && event.target.matches('button.className')) {
console.log('Button clicked:', event.target.textContent);
}
});

Event delegation allows you to manage events efficiently by adding a single event listener to a common parent element and handling events for multiple child elements.

44. Avoid Using `eval()`

Problem: Using `eval()` can lead to security vulnerabilities and performance issues.

Solution: Avoid using `eval()` and use safer alternatives.

// Avoid
const code = 'console.log("Hello, world!")';
eval(code); // "Hello, world!"
// Use safer alternatives
const func = new Function('console.log("Hello, world!")');
func(); // "Hello, world!"

Avoiding `eval()` helps prevent security vulnerabilities and performance issues, making your code more secure and efficient.

45. Using `for…of` for Iteration

Problem: Iterating over arrays with `for…in` can be error-prone.

Solution: Use `for…of` to iterate over arrays and other iterable objects.

const arr = [1, 2, 3, 4, 5];
for (const value of arr) {
console.log(value);
}
// 1
// 2
// 3
// 4
// 5

`for…of` provides a simple and safe way

 

https://blog.devgenius.io/45-javascript-super-hacks-every-developer-should-know-92aecfb33ee8

반응형

+ Recent posts